[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
@@ -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.incremental
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import java.util.concurrent.ConcurrentHashMap
@Suppress("unused")
class EnumWhenTrackerImpl: EnumWhenTracker {
private val whenExpressionFilePathToEnumClass = ConcurrentHashMap<String, MutableSet<String>>()
val whenExpressionFilePathToEnumClassMap: Map<String, Collection<String>>
get() = whenExpressionFilePathToEnumClass
override fun report(whenExpressionFilePath: String, enumClassFqName: String) {
whenExpressionFilePathToEnumClass.getOrPut(whenExpressionFilePath) { hashSetOf() }.add(enumClassFqName)
}
}
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.cli.jvm.config.ClassicFrontendSpecificJvmConfigurati
import org.jetbrains.kotlin.cli.jvm.config.configureJdkClasspathRoots
import org.jetbrains.kotlin.codegen.CompilationException
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -209,6 +210,8 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
putIfNotNull(CommonConfigurationKeys.INLINE_CONST_TRACKER, services[InlineConstTracker::class.java])
putIfNotNull(CommonConfigurationKeys.ENUM_WHEN_TRACKER, services[EnumWhenTracker::class.java])
putIfNotNull(
JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS,
services[IncrementalCompilationComponents::class.java]
@@ -214,6 +214,7 @@ object FirKotlinToJvmBytecodeCompiler {
sourceScope,
librariesScope,
lookupTracker = moduleConfiguration.get(CommonConfigurationKeys.LOOKUP_TRACKER),
enumWhenTracker = moduleConfiguration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER),
providerAndScopeForIncrementalCompilation,
firExtensionRegistrars,
needRegisterJavaElementFinder,
@@ -43,6 +43,7 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.frontend.java.di.createContainerForLazyResolveWithJava
import org.jetbrains.kotlin.frontend.java.di.initJvmBuiltInsForTopDownAnalysis
import org.jetbrains.kotlin.frontend.java.di.initialize
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
@@ -163,6 +164,7 @@ object TopDownAnalyzerFacadeForJVM {
val lookupTracker = configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER) ?: LookupTracker.DO_NOTHING
val expectActualTracker = configuration.get(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER) ?: ExpectActualTracker.DoNothing
val inlineConstTracker = configuration.get(CommonConfigurationKeys.INLINE_CONST_TRACKER) ?: InlineConstTracker.DoNothing
val enumWhenTracker = configuration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER) ?: EnumWhenTracker.DoNothing
val targetIds = configuration.get(JVMConfigurationKeys.MODULES)?.map(::TargetId)
val separateModules = !configuration.getBoolean(JVMConfigurationKeys.USE_SINGLE_MODULE)
@@ -197,7 +199,7 @@ object TopDownAnalyzerFacadeForJVM {
val dependenciesContainer = createContainerForLazyResolveWithJava(
jvmPlatform,
dependenciesContext, trace, DeclarationProviderFactory.EMPTY, dependencyScope, moduleClassResolver,
targetEnvironment, lookupTracker, expectActualTracker, inlineConstTracker,
targetEnvironment, lookupTracker, expectActualTracker, inlineConstTracker, enumWhenTracker,
packagePartProvider(dependencyScope), languageVersionSettings,
useBuiltInsProvider = true,
configureJavaClassFinder = configureJavaClassFinder,
@@ -232,7 +234,7 @@ object TopDownAnalyzerFacadeForJVM {
val container = createContainerForLazyResolveWithJava(
jvmPlatform,
moduleContext, trace, declarationProviderFactory(storageManager, files), sourceScope, moduleClassResolver,
targetEnvironment, lookupTracker, expectActualTracker, inlineConstTracker,
targetEnvironment, lookupTracker, expectActualTracker, inlineConstTracker, enumWhenTracker,
partProvider, languageVersionSettings,
useBuiltInsProvider = true,
configureJavaClassFinder = configureJavaClassFinder,
@@ -403,6 +403,7 @@ fun createSession(
projectEnvironment.getSearchScopeForProjectJavaSources(),
librariesScope,
lookupTracker = moduleConfiguration.get(CommonConfigurationKeys.LOOKUP_TRACKER),
enumWhenTracker = moduleConfiguration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER),
providerAndScopeForIncrementalCompilation,
extensionRegistrars = (projectEnvironment as? VfsBasedProjectEnvironment)?.let { FirExtensionRegistrar.getInstances(it.project) }
?: emptyList(),
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.config
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -43,6 +44,9 @@ object CommonConfigurationKeys {
@JvmField
val INLINE_CONST_TRACKER = CompilerConfigurationKey.create<InlineConstTracker>("inline constant tracker")
@JvmField
val ENUM_WHEN_TRACKER = CompilerConfigurationKey.create<EnumWhenTracker>("enum when tracker")
@JvmField
val METADATA_VERSION = CompilerConfigurationKey.create<BinaryVersion>("metadata version")
@@ -17,10 +17,7 @@
package org.jetbrains.kotlin.daemon.client
import org.jetbrains.kotlin.daemon.common.*
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupInfo
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.components.*
import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
import org.jetbrains.kotlin.incremental.js.JsInlineFunctionHash
@@ -38,6 +35,7 @@ open class CompilerCallbackServicesFacadeServer(
val compilationCanceledStatus: CompilationCanceledStatus? = null,
val expectActualTracker: ExpectActualTracker? = null,
val inlineConstTracker: InlineConstTracker? = null,
val enumWhenTracker: EnumWhenTracker? = null,
val incrementalResultsConsumer: IncrementalResultsConsumer? = null,
val incrementalDataProvider: IncrementalDataProvider? = null,
port: Int = SOCKET_ANY_FREE_PORT
@@ -57,6 +55,8 @@ open class CompilerCallbackServicesFacadeServer(
override fun hasInlineConstTracker(): Boolean = inlineConstTracker != null
override fun hasEnumWhenTracker(): Boolean = enumWhenTracker != null
override fun hasIncrementalResultsConsumer(): Boolean = incrementalResultsConsumer != null
override fun hasIncrementalDataProvider(): Boolean = incrementalDataProvider != null
@@ -124,6 +124,10 @@ open class CompilerCallbackServicesFacadeServer(
inlineConstTracker?.report(filePath, owner, name, constType) ?: throw NullPointerException("inlineConstTracker was not initialized")
}
override fun enumWhenTracker_report(whenUsageClassPath: String, enumClassFqName: String) {
enumWhenTracker?.report(whenUsageClassPath, enumClassFqName) ?: throw NullPointerException("enumWhenTracker was not initialized")
}
override fun incrementalResultsConsumer_processHeader(headerMetadata: ByteArray) {
incrementalResultsConsumer!!.processHeader(headerMetadata)
}
@@ -51,6 +51,9 @@ interface CompilerCallbackServicesFacade : Remote {
@Throws(RemoteException::class)
fun hasInlineConstTracker(): Boolean
@Throws(RemoteException::class)
fun hasEnumWhenTracker(): Boolean
@Throws(RemoteException::class)
fun hasIncrementalResultsConsumer(): Boolean
@@ -109,6 +112,11 @@ interface CompilerCallbackServicesFacade : Remote {
@Throws(RemoteException::class)
fun inlineConstTracker_report(filePath: String, owner: String, name: String, constType: String)
// ---------------------------------------------------
// EnumWhenTracker
@Throws(RemoteException::class)
fun enumWhenTracker_report(whenUsageClassPath: String, enumClassFqName: String)
// ---------------------------------------------------
// IncrementalResultsConsumer (js)
@Throws(RemoteException::class)
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.daemon.report.DaemonMessageReporter
import org.jetbrains.kotlin.daemon.report.DaemonMessageReporterPrintStreamAdapter
import org.jetbrains.kotlin.daemon.report.getBuildReporter
import org.jetbrains.kotlin.incremental.*
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
@@ -891,6 +892,9 @@ class CompileServiceImpl(
if (facade.hasInlineConstTracker()) {
builder.register(InlineConstTracker::class.java, RemoteInlineConstTracker(facade, rpcProfiler))
}
if (facade.hasEnumWhenTracker()) {
builder.register(EnumWhenTracker::class.java, RemoteEnumWhenTracker(facade, rpcProfiler))
}
if (facade.hasIncrementalResultsConsumer()) {
builder.register(IncrementalResultsConsumer::class.java, RemoteIncrementalResultsConsumer(facade, eventManager, rpcProfiler))
}
@@ -0,0 +1,22 @@
/*
* 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.daemon
import org.jetbrains.kotlin.daemon.common.DummyProfiler
import org.jetbrains.kotlin.daemon.common.Profiler
import org.jetbrains.kotlin.daemon.common.withMeasure
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
class RemoteEnumWhenTracker(
@Suppress("DEPRECATION") val facade: org.jetbrains.kotlin.daemon.common.CompilerCallbackServicesFacade,
val profiler: Profiler = DummyProfiler()
): EnumWhenTracker {
override fun report(whenExpressionFilePath: String, enumClassFqName: String) {
profiler.withMeasure(this) {
facade.enumWhenTracker_report(whenExpressionFilePath, enumClassFqName)
}
}
}
@@ -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)
}
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.frontend.di.configureIncrementalCompilation
import org.jetbrains.kotlin.frontend.di.configureModule
import org.jetbrains.kotlin.frontend.di.configureStandardResolveComponents
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -63,6 +64,7 @@ fun createContainerForLazyResolveWithJava(
lookupTracker: LookupTracker,
expectActualTracker: ExpectActualTracker,
inlineConstTracker: InlineConstTracker,
enumWhenTracker: EnumWhenTracker,
packagePartProvider: PackagePartProvider,
languageVersionSettings: LanguageVersionSettings,
useBuiltInsProvider: Boolean,
@@ -76,7 +78,7 @@ fun createContainerForLazyResolveWithJava(
sealedInheritorsProvider
)
configureIncrementalCompilation(lookupTracker, expectActualTracker, inlineConstTracker)
configureIncrementalCompilation(lookupTracker, expectActualTracker, inlineConstTracker, enumWhenTracker)
configureStandardResolveComponents()
useInstance(moduleContentScope)
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.context.ModuleContext
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.frontend.java.di.createContainerForLazyResolveWithJava
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -114,6 +115,7 @@ class JvmResolverForModuleFactory(
lookupTracker,
ExpectActualTracker.DoNothing,
InlineConstTracker.DoNothing,
EnumWhenTracker.DoNothing,
packagePartProvider,
languageVersionSettings,
sealedInheritorsProvider = sealedInheritorsProvider,
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
import org.jetbrains.kotlin.idea.MainFunctionDetector
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
@@ -49,6 +50,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
import org.jetbrains.kotlin.resolve.calls.util.*
import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
@@ -58,13 +60,15 @@ import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
import org.jetbrains.kotlin.types.isFlexible
import org.jetbrains.kotlin.types.typeUtil.isBooleanOrNullableBoolean
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.util.record
class ControlFlowInformationProviderImpl private constructor(
private val subroutine: KtElement,
private val trace: BindingTrace,
private val pseudocode: Pseudocode,
private val languageVersionSettings: LanguageVersionSettings,
private val diagnosticSuppressor: PlatformDiagnosticSuppressor
private val diagnosticSuppressor: PlatformDiagnosticSuppressor,
private val enumWhenTracker: EnumWhenTracker?
) : ControlFlowInformationProvider {
private val pseudocodeVariablesData by lazy {
PseudocodeVariablesData(pseudocode, trace.bindingContext)
@@ -74,13 +78,15 @@ class ControlFlowInformationProviderImpl private constructor(
declaration: KtElement,
trace: BindingTrace,
languageVersionSettings: LanguageVersionSettings,
diagnosticSuppressor: PlatformDiagnosticSuppressor
diagnosticSuppressor: PlatformDiagnosticSuppressor,
enumWhenTracker: EnumWhenTracker? = null
) : this(
declaration,
trace,
ControlFlowProcessor(trace, languageVersionSettings).generatePseudocode(declaration),
languageVersionSettings,
diagnosticSuppressor
diagnosticSuppressor,
enumWhenTracker
)
override fun checkForLocalClassOrObjectMode() {
@@ -231,7 +237,7 @@ class ControlFlowInformationProviderImpl private constructor(
val expectedType = functionDescriptor?.returnType
val providerForLocalDeclaration = ControlFlowInformationProviderImpl(
element, trace, localDeclarationInstruction.body, languageVersionSettings, diagnosticSuppressor
element, trace, localDeclarationInstruction.body, languageVersionSettings, diagnosticSuppressor, enumWhenTracker
)
providerForLocalDeclaration.checkFunction(expectedType)
@@ -1057,6 +1063,9 @@ class ControlFlowInformationProviderImpl private constructor(
}
continue
}
enumWhenTracker?.record(subjectType, subjectExpression, elseEntry)
if (!usedAsExpression) {
if (languageVersionSettings.supportsFeature(LanguageFeature.WarnAboutNonExhaustiveWhenOnAlgebraicTypes)) {
// report warnings on all non-exhaustive when's with algebraic subject
@@ -1318,9 +1327,10 @@ class ControlFlowInformationProviderImpl private constructor(
declaration: KtElement,
trace: BindingTrace,
languageVersionSettings: LanguageVersionSettings,
diagnosticSuppressor: PlatformDiagnosticSuppressor
diagnosticSuppressor: PlatformDiagnosticSuppressor,
enumWhenTracker: EnumWhenTracker
): ControlFlowInformationProvider =
ControlFlowInformationProviderImpl(declaration, trace, languageVersionSettings, diagnosticSuppressor)
ControlFlowInformationProviderImpl(declaration, trace, languageVersionSettings, diagnosticSuppressor, enumWhenTracker)
}
companion object {
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.cfg
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor
@@ -24,6 +25,7 @@ interface ControlFlowInformationProvider {
trace: BindingTrace,
languageVersionSettings: LanguageVersionSettings,
diagnosticSuppressor: PlatformDiagnosticSuppressor,
enumWhenTracker: EnumWhenTracker
): ControlFlowInformationProvider
}
}
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.contracts.ContractDeserializerImpl
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
import org.jetbrains.kotlin.extensions.TypeAttributeTranslatorExtension
import org.jetbrains.kotlin.idea.MainFunctionDetector
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -130,10 +131,16 @@ fun StorageComponentContainer.configureStandardResolveComponents() {
useImpl<AnnotationResolverImpl>()
}
fun StorageComponentContainer.configureIncrementalCompilation(lookupTracker: LookupTracker, expectActualTracker: ExpectActualTracker, inlineConstTracker: InlineConstTracker) {
fun StorageComponentContainer.configureIncrementalCompilation(
lookupTracker: LookupTracker,
expectActualTracker: ExpectActualTracker,
inlineConstTracker: InlineConstTracker,
enumWhenTracker: EnumWhenTracker
) {
useInstance(lookupTracker)
useInstance(expectActualTracker)
useInstance(inlineConstTracker)
useInstance(enumWhenTracker)
}
fun createContainerForBodyResolve(
@@ -209,6 +216,7 @@ fun createContainerForLazyLocalClassifierAnalyzer(
useInstance(lookupTracker)
useInstance(ExpectActualTracker.DoNothing)
useInstance(InlineConstTracker.DoNothing)
useInstance(EnumWhenTracker.DoNothing)
useImpl<LazyTopDownAnalyzer>()
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings;
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor;
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor;
import org.jetbrains.kotlin.types.KotlinType;
@@ -38,19 +39,22 @@ public class ControlFlowAnalyzer {
private final LanguageVersionSettings languageVersionSettings;
private final PlatformDiagnosticSuppressor diagnosticSuppressor;
private final ControlFlowInformationProvider.Factory controlFlowInformationProviderFactory;
private final EnumWhenTracker enumWhenTracker;
public ControlFlowAnalyzer(
@NotNull BindingTrace trace,
@NotNull KotlinBuiltIns builtIns,
@NotNull LanguageVersionSettings languageVersionSettings,
@NotNull PlatformDiagnosticSuppressor diagnosticSuppressor,
@NotNull ControlFlowInformationProvider.Factory controlFlowInformationProviderFactory
@NotNull ControlFlowInformationProvider.Factory controlFlowInformationProviderFactory,
@NotNull EnumWhenTracker enumWhenTracker
) {
this.trace = trace;
this.builtIns = builtIns;
this.languageVersionSettings = languageVersionSettings;
this.diagnosticSuppressor = diagnosticSuppressor;
this.controlFlowInformationProviderFactory = controlFlowInformationProviderFactory;
this.enumWhenTracker = enumWhenTracker;
}
public void process(@NotNull BodiesResolveContext c) {
@@ -84,7 +88,7 @@ public class ControlFlowAnalyzer {
private void checkSecondaryConstructor(@NotNull KtSecondaryConstructor constructor) {
ControlFlowInformationProvider controlFlowInformationProvider =
controlFlowInformationProviderFactory.createControlFlowInformationProvider(
constructor, trace, languageVersionSettings, diagnosticSuppressor
constructor, trace, languageVersionSettings, diagnosticSuppressor, enumWhenTracker
);
controlFlowInformationProvider.checkDeclaration();
controlFlowInformationProvider.checkFunction(builtIns.getUnitType());
@@ -95,7 +99,7 @@ public class ControlFlowAnalyzer {
// or initialization of properties corresponds to a package declared in a file
ControlFlowInformationProvider controlFlowInformationProvider =
controlFlowInformationProviderFactory.createControlFlowInformationProvider(
(KtElement) declarationContainer, trace, languageVersionSettings, diagnosticSuppressor
(KtElement) declarationContainer, trace, languageVersionSettings, diagnosticSuppressor, enumWhenTracker
);
if (c.getTopDownAnalysisMode().isLocalDeclarations()) {
controlFlowInformationProvider.checkForLocalClassOrObjectMode();
@@ -120,7 +124,7 @@ public class ControlFlowAnalyzer {
) {
ControlFlowInformationProvider controlFlowInformationProvider =
controlFlowInformationProviderFactory.createControlFlowInformationProvider(
function, trace, languageVersionSettings, diagnosticSuppressor
function, trace, languageVersionSettings, diagnosticSuppressor, enumWhenTracker
);
if (c.getTopDownAnalysisMode().isLocalDeclarations()) {
controlFlowInformationProvider.checkForLocalClassOrObjectMode();
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.types.error.ErrorUtils;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt;
import org.jetbrains.kotlin.util.KotlinFrontEndException;
import org.jetbrains.kotlin.util.LookupTrackerUtilKt;
import org.jetbrains.kotlin.util.IncrementalTrackerUtilKt;
import org.jetbrains.kotlin.util.PerformanceCounter;
import org.jetbrains.kotlin.util.ReenteringLazyValueComputationException;
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments;
@@ -236,7 +236,7 @@ public abstract class ExpressionTypingVisitorDispatcher extends KtVisitor<Kotlin
KotlinType resultType = typeInfo.getType();
if (resultType != null) {
LookupTrackerUtilKt.record(lookupTracker, expression, resultType);
IncrementalTrackerUtilKt.record(lookupTracker, expression, resultType);
}
}
@@ -18,11 +18,16 @@ package org.jetbrains.kotlin.util
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.containingPackage
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.record
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.psi.KtWhenEntry
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.isError
import org.jetbrains.kotlin.types.typeUtil.isUnit
@@ -50,3 +55,20 @@ fun LookupTracker.record(expression: KtExpression, type: KotlinType) {
}
}
}
fun EnumWhenTracker.record(subjectType: KotlinType?, subjectExpression: KtExpression, elseEntry: KtWhenEntry?) {
if (elseEntry != null) return
if (subjectExpression !is KtNameReferenceExpression) return
val declarationDescriptor = subjectType?.constructor?.declarationDescriptor ?: return
val containingPackage = declarationDescriptor.containingPackage()?.toString() ?: return
val fqName = declarationDescriptor.fqNameSafe.asString()
val filePath = subjectExpression.containingFile.virtualFile?.path ?: return
val owner = if (fqName.startsWith("$containingPackage.")) {
containingPackage + "." + fqName.substring(containingPackage.length + 1).replace(".", "$")
} else {
fqName.replace(".", "$")
}
this.report(filePath, owner)
}
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDependenciesImpl
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.frontend.java.di.createContainerForLazyResolveWithJava
import org.jetbrains.kotlin.frontend.java.di.initJvmBuiltInsForTopDownAnalysis
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -208,6 +209,7 @@ class ClassicFrontendFacade(
lookupTracker = LookupTracker.DO_NOTHING,
expectActualTracker = ExpectActualTracker.DoNothing,
inlineConstTracker = InlineConstTracker.DoNothing,
enumWhenTracker = EnumWhenTracker.DoNothing,
packagePartProvider = packagePartProviderFactory(moduleContentScope),
languageVersionSettings = module.languageVersionSettings,
useBuiltInsProvider = true
@@ -93,6 +93,7 @@ class FirFrontendFacade(
PsiBasedProjectFileSearchScope(sourcesScope),
PsiBasedProjectFileSearchScope(librariesScope),
lookupTracker = null,
enumWhenTracker = null,
incrementalCompilationContext = null,
extensionRegistrars = FirExtensionRegistrar.getInstances(project),
needRegisterJavaElementFinder = true,
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.frontend.java.di.createContainerForLazyResolveWithJava
import org.jetbrains.kotlin.frontend.java.di.initJvmBuiltInsForTopDownAnalysis
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -428,7 +429,7 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() {
moduleContentScope,
moduleClassResolver,
CompilerEnvironment,
LookupTracker.DO_NOTHING, ExpectActualTracker.DoNothing, InlineConstTracker.DoNothing,
LookupTracker.DO_NOTHING, ExpectActualTracker.DoNothing, InlineConstTracker.DoNothing, EnumWhenTracker.DoNothing,
environment.createPackagePartProvider(moduleContentScope),
languageVersionSettings,
useBuiltInsProvider = true
@@ -99,6 +99,7 @@ abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() {
javaSourcesScope = PsiBasedProjectFileSearchScope(scope),
librariesScope = PsiBasedProjectFileSearchScope(allProjectScope),
lookupTracker = null,
enumWhenTracker = null,
incrementalCompilationContext = null,
extensionRegistrars = emptyList(),
needRegisterJavaElementFinder = true
@@ -41,6 +41,7 @@ fun createSessionForTests(
sourceScope,
librariesScope,
lookupTracker = null,
enumWhenTracker = null,
incrementalCompilationContext = null,
extensionRegistrars = emptyList(),
needRegisterJavaElementFinder = true,
@@ -72,6 +73,7 @@ fun createSessionForTests(
PsiBasedProjectFileSearchScope(sourceScope),
PsiBasedProjectFileSearchScope(librariesScope),
lookupTracker = null,
enumWhenTracker = null,
incrementalCompilationContext = null,
extensionRegistrars = emptyList(),
needRegisterJavaElementFinder = true,
@@ -0,0 +1,26 @@
/*
* 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.incremental.components
import org.jetbrains.kotlin.container.DefaultImplementation
/**
* EnumWhenTracker is used to track Java enum classes used in Kotlin when expressions for correct build scope expansion in IC during JPS build.
*/
@DefaultImplementation(EnumWhenTracker.DoNothing::class)
interface EnumWhenTracker {
/**
* Report Java enum class, which FqName is [enumClassFqName].
* This enum class is used in Kotlin file with [whenExpressionFilePath] path in when expression.
* Format of [enumClassFqName] class is "package.Outer$Inner"
*/
fun report(whenExpressionFilePath: String, enumClassFqName: String)
object DoNothing : EnumWhenTracker {
override fun report(whenExpressionFilePath: String, enumClassFqName: String) {}
}
}
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.daemon.client.CompilerCallbackServicesFacadeServer
import org.jetbrains.kotlin.daemon.client.reportFromDaemon
import org.jetbrains.kotlin.daemon.common.JpsCompilerServicesFacade
import org.jetbrains.kotlin.daemon.common.SOCKET_ANY_FREE_PORT
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -38,6 +39,7 @@ internal class JpsCompilerServicesFacadeImpl(
env.services[CompilationCanceledStatus::class.java],
env.services[ExpectActualTracker::class.java],
env.services[InlineConstTracker::class.java],
env.services[EnumWhenTracker::class.java],
env.services[IncrementalResultsConsumer::class.java],
env.services[IncrementalDataProvider::class.java],
port
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.incremental.*
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.build.report.ICReporterBase
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.jps.KotlinJpsBundle
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache
@@ -236,6 +237,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
LookupTracker.DO_NOTHING,
ExpectActualTracker.DoNothing,
InlineConstTracker.DoNothing,
EnumWhenTracker.DoNothing,
chunk,
messageCollector
) ?: return
@@ -356,7 +358,10 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
if (!kotlinChunk.haveSameCompiler) {
messageCollector.report(
ERROR,
KotlinJpsBundle.message("error.text.cyclically.dependent.modules.0.should.have.same.compiler", kotlinChunk.presentableModulesToCompilersList)
KotlinJpsBundle.message(
"error.text.cyclically.dependent.modules.0.should.have.same.compiler",
kotlinChunk.presentableModulesToCompilersList
)
)
return ABORT
}
@@ -394,8 +399,9 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val targetsWithoutOutputDir = targets.filter { it.outputDir == null }
if (targetsWithoutOutputDir.isNotEmpty()) {
messageCollector.report(ERROR,
KotlinJpsBundle.message("error.text.output.directory.not.specified.for.0", targetsWithoutOutputDir.joinToString())
messageCollector.report(
ERROR,
KotlinJpsBundle.message("error.text.output.directory.not.specified.for.0", targetsWithoutOutputDir.joinToString())
)
return ABORT
}
@@ -405,6 +411,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val exceptActualTracer = ExpectActualTrackerImpl()
val incrementalCaches = kotlinChunk.loadCaches()
val inlineConstTracker = InlineConstTrackerImpl()
val enumWhenTracker = EnumWhenTrackerImpl()
val environment = createCompileEnvironment(
context,
representativeTarget,
@@ -412,6 +419,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
lookupTracker,
exceptActualTracer,
inlineConstTracker,
enumWhenTracker,
chunk,
messageCollector
) ?: return ABORT
@@ -604,11 +612,19 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
lookupTracker: LookupTracker,
exceptActualTracer: ExpectActualTracker,
inlineConstTracker: InlineConstTracker,
enumWhenTracker: EnumWhenTracker,
chunk: ModuleChunk,
messageCollector: MessageCollectorAdapter
): JpsCompilerEnvironment? {
val compilerServices = with(Services.Builder()) {
kotlinModuleBuilderTarget.makeServices(this, incrementalCaches, lookupTracker, exceptActualTracer, inlineConstTracker)
kotlinModuleBuilderTarget.makeServices(
this,
incrementalCaches,
lookupTracker,
exceptActualTracer,
inlineConstTracker,
enumWhenTracker
)
build()
}
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.ChangesCollector
import org.jetbrains.kotlin.incremental.IncrementalJsCache
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -70,9 +71,10 @@ class KotlinJsModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleBu
incrementalCaches: Map<KotlinModuleBuildTarget<*>, JpsIncrementalCache>,
lookupTracker: LookupTracker,
exceptActualTracer: ExpectActualTracker,
inlineConstTracker: InlineConstTracker
inlineConstTracker: InlineConstTracker,
enumWhenTracker: EnumWhenTracker
) {
super.makeServices(builder, incrementalCaches, lookupTracker, exceptActualTracer, inlineConstTracker)
super.makeServices(builder, incrementalCaches, lookupTracker, exceptActualTracer, inlineConstTracker, enumWhenTracker)
with(builder) {
register(IncrementalResultsConsumer::class.java, IncrementalResultsConsumerImpl())
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.*
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -80,9 +81,10 @@ class KotlinJvmModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleB
incrementalCaches: Map<KotlinModuleBuildTarget<*>, JpsIncrementalCache>,
lookupTracker: LookupTracker,
exceptActualTracer: ExpectActualTracker,
inlineConstTracker: InlineConstTracker
inlineConstTracker: InlineConstTracker,
enumWhenTracker: EnumWhenTracker
) {
super.makeServices(builder, incrementalCaches, lookupTracker, exceptActualTracer, inlineConstTracker)
super.makeServices(builder, incrementalCaches, lookupTracker, exceptActualTracer, inlineConstTracker, enumWhenTracker)
with(builder) {
register(
@@ -363,6 +365,7 @@ class KotlinJvmModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleB
val previousMappings = localContext.projectDescriptor.dataManager.mappings
val callback = JavaBuilderUtil.getDependenciesRegistrar(localContext)
val inlineConstTracker = environment.services[InlineConstTracker::class.java] as InlineConstTrackerImpl
val enumWhenTracker = environment.services[EnumWhenTracker::class.java] as EnumWhenTrackerImpl
val targetDirtyFiles: Map<ModuleBuildTarget, Set<File>> = chunk.targets.keysToMap {
val files = HashSet<File>()
@@ -393,24 +396,8 @@ class KotlinJvmModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleB
// process inlineConstTracker
for (sourceFile: File in sourceFiles) {
val cRefs = inlineConstTracker.inlineConstMap[sourceFile.path]?.mapNotNull { cRef: ConstantRef ->
val descriptor = when (cRef.constType) {
"Byte" -> "B"
"Short" -> "S"
"Int" -> "I"
"Long" -> "J"
"Float" -> "F"
"Double" -> "D"
"Boolean" -> "Z"
"Char" -> "C"
"String" -> "Ljava/lang/String;"
else -> null
} ?: return@mapNotNull null
Callbacks.createConstantReference(cRef.owner, cRef.name, descriptor)
} ?: continue
val className = output.outputClass.className.internalName
callback.registerConstantReferences(className, cRefs)
processInlineConstTracker(inlineConstTracker, sourceFile, output, callback)
processEnumWhenTracker(enumWhenTracker, sourceFile, output, callback)
}
callback.associate(
@@ -425,4 +412,30 @@ class KotlinJvmModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleB
JavaBuilderUtil.registerFilesToCompile(localContext, allCompiled)
JavaBuilderUtil.registerSuccessfullyCompiled(localContext, allCompiled)
}
private fun processInlineConstTracker(inlineConstTracker: InlineConstTrackerImpl, sourceFile: File, output: GeneratedJvmClass, callback: Callbacks.Backend) {
val cRefs = inlineConstTracker.inlineConstMap[sourceFile.path]?.mapNotNull { cRef: ConstantRef ->
val descriptor = when (cRef.constType) {
"Byte" -> "B"
"Short" -> "S"
"Int" -> "I"
"Long" -> "J"
"Float" -> "F"
"Double" -> "D"
"Boolean" -> "Z"
"Char" -> "C"
"String" -> "Ljava/lang/String;"
else -> null
} ?: return@mapNotNull null
Callbacks.createConstantReference(cRef.owner, cRef.name, descriptor)
} ?: return
val className = output.outputClass.className.internalName
callback.registerConstantReferences(className, cRefs)
}
private fun processEnumWhenTracker(enumWhenTracker: EnumWhenTrackerImpl, sourceFile: File, output: GeneratedJvmClass, callback: Callbacks.Backend) {
val enumFqNameClasses = enumWhenTracker.whenExpressionFilePathToEnumClassMap[sourceFile.path]?.map { "$it.*" } ?: return
callback.registerImports(output.outputClass.className.internalName, listOf(), enumFqNameClasses)
}
}
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.incremental.ChangesCollector
import org.jetbrains.kotlin.incremental.ExpectActualTrackerImpl
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -272,7 +273,8 @@ abstract class KotlinModuleBuildTarget<BuildMetaInfoType : BuildMetaInfo> intern
incrementalCaches: Map<KotlinModuleBuildTarget<*>, JpsIncrementalCache>,
lookupTracker: LookupTracker,
exceptActualTracer: ExpectActualTracker,
inlineConstTracker: InlineConstTracker
inlineConstTracker: InlineConstTracker,
enumWhenTracker: EnumWhenTracker
) {
with(builder) {
register(LookupTracker::class.java, lookupTracker)
@@ -283,6 +285,7 @@ abstract class KotlinModuleBuildTarget<BuildMetaInfoType : BuildMetaInfo> intern
}
})
register(InlineConstTracker::class.java, inlineConstTracker)
register(EnumWhenTracker::class.java, enumWhenTracker)
}
}
@@ -8,9 +8,6 @@ Exit code: NOTHING_DONE
Compiling files:
src/Enum.java
End of files
================ Step #2 =================
Cleaning output files:
out/production/module/META-INF/module.kotlin_module
out/production/module/UseKt$WhenMappings.class
@@ -19,5 +16,21 @@ End of files
Compiling files:
src/use.kt
End of files
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
'when' expression must be exhaustive, add necessary 'C' branch or 'else' branch instead
================ Step #2 =================
Cleaning output files:
out/production/module/Enum.class
End of files
Compiling files:
src/use.kt
End of files
Exit code: OK
------------------------------------------
Compiling files:
src/Enum.java
End of files
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.frontend.di.configureIncrementalCompilation
import org.jetbrains.kotlin.frontend.di.configureModule
import org.jetbrains.kotlin.frontend.di.configureStandardResolveComponents
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -47,6 +48,7 @@ fun createContainerForJS(
lookupTracker: LookupTracker,
expectActualTracker: ExpectActualTracker,
inlineConstTracker: InlineConstTracker,
enumWhenTracker: EnumWhenTracker,
additionalPackages: List<PackageFragmentProvider>,
targetEnvironment: TargetEnvironment,
): StorageComponentContainer {
@@ -59,7 +61,7 @@ fun createContainerForJS(
languageVersionSettings
)
configureIncrementalCompilation(lookupTracker, expectActualTracker, inlineConstTracker)
configureIncrementalCompilation(lookupTracker, expectActualTracker, inlineConstTracker, enumWhenTracker)
configureStandardResolveComponents()
useInstance(declarationProviderFactory)
@@ -83,11 +85,12 @@ fun createTopDownAnalyzerForJs(
lookupTracker: LookupTracker,
expectActualTracker: ExpectActualTracker,
inlineConstTracker: InlineConstTracker,
enumWhenTracker: EnumWhenTracker,
additionalPackages: List<PackageFragmentProvider>,
targetEnvironment: TargetEnvironment,
): LazyTopDownAnalyzer {
return createContainerForJS(
moduleContext, bindingTrace, declarationProviderFactory, languageVersionSettings,
lookupTracker, expectActualTracker, inlineConstTracker, additionalPackages, targetEnvironment
lookupTracker, expectActualTracker, inlineConstTracker, enumWhenTracker, additionalPackages, targetEnvironment
).get<LazyTopDownAnalyzer>()
}
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.frontend.js.di.createContainerForJS
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -107,6 +108,7 @@ abstract class AbstractTopDownAnalyzerFacadeForJS {
val lookupTracker = configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER) ?: LookupTracker.DO_NOTHING
val expectActualTracker = configuration.get(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER) ?: ExpectActualTracker.DoNothing
val inlineConstTracker = configuration.get(CommonConfigurationKeys.INLINE_CONST_TRACKER) ?: InlineConstTracker.DoNothing
val enumWhenTracker = configuration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER) ?: EnumWhenTracker.DoNothing
val languageVersionSettings = configuration.languageVersionSettings
val packageFragment = configuration[JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER]?.let {
loadIncrementalCacheMetadata(it, moduleContext, lookupTracker, languageVersionSettings)
@@ -119,6 +121,7 @@ abstract class AbstractTopDownAnalyzerFacadeForJS {
lookupTracker,
expectActualTracker,
inlineConstTracker,
enumWhenTracker,
additionalPackages + listOfNotNull(packageFragment),
targetEnvironment,
)
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.frontend.js.di.createTopDownAnalyzerForJs
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -56,6 +57,7 @@ abstract class AbstractJsScriptlikeCodeAnalyser(
val lookupTracker = LookupTracker.DO_NOTHING
val expectActualTracker = ExpectActualTracker.DoNothing
val inlineConstTracker = InlineConstTracker.DoNothing
val enumWhenTracker = EnumWhenTracker.DoNothing
val additionalPackages = emptyList<PackageFragmentProvider>()
val moduleDescriptor = moduleContext.module
@@ -68,6 +70,7 @@ abstract class AbstractJsScriptlikeCodeAnalyser(
lookupTracker,
expectActualTracker,
inlineConstTracker,
enumWhenTracker,
additionalPackages,
CompilerEnvironment,
)