diff --git a/build-common/src/org/jetbrains/kotlin/incremental/EnumWhenTrackerImpl.kt b/build-common/src/org/jetbrains/kotlin/incremental/EnumWhenTrackerImpl.kt new file mode 100644 index 00000000000..0708f2430d2 --- /dev/null +++ b/build-common/src/org/jetbrains/kotlin/incremental/EnumWhenTrackerImpl.kt @@ -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>() + + val whenExpressionFilePathToEnumClassMap: Map> + get() = whenExpressionFilePathToEnumClass + + override fun report(whenExpressionFilePath: String, enumClassFqName: String) { + whenExpressionFilePathToEnumClass.getOrPut(whenExpressionFilePath) { hashSetOf() }.add(enumClassFqName) + } +} \ No newline at end of file diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt index d8342cc1466..2db08cf0b49 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt @@ -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() { 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] diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt index dbbec71d3c0..2db8cd16b44 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt @@ -214,6 +214,7 @@ object FirKotlinToJvmBytecodeCompiler { sourceScope, librariesScope, lookupTracker = moduleConfiguration.get(CommonConfigurationKeys.LOOKUP_TRACKER), + enumWhenTracker = moduleConfiguration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER), providerAndScopeForIncrementalCompilation, firExtensionRegistrars, needRegisterJavaElementFinder, diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/TopDownAnalyzerFacadeForJVM.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/TopDownAnalyzerFacadeForJVM.kt index 255f566c198..837bd310abd 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/TopDownAnalyzerFacadeForJVM.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/TopDownAnalyzerFacadeForJVM.kt @@ -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, diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt index b3ca6807974..e4feb3ea911 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt @@ -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(), diff --git a/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt b/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt index a2efefab453..7caa6cf2483 100644 --- a/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt +++ b/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt @@ -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("inline constant tracker") + @JvmField + val ENUM_WHEN_TRACKER = CompilerConfigurationKey.create("enum when tracker") + @JvmField val METADATA_VERSION = CompilerConfigurationKey.create("metadata version") diff --git a/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/CompilerCallbackServicesFacadeServer.kt b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/CompilerCallbackServicesFacadeServer.kt index 1cdc60d2c01..16ed5902b82 100644 --- a/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/CompilerCallbackServicesFacadeServer.kt +++ b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/CompilerCallbackServicesFacadeServer.kt @@ -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) } diff --git a/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompilerCallbackServicesFacade.kt b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompilerCallbackServicesFacade.kt index 647f008fa07..bae65e7443a 100644 --- a/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompilerCallbackServicesFacade.kt +++ b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompilerCallbackServicesFacade.kt @@ -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) diff --git a/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt b/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt index aef6cb32237..223261d78a6 100644 --- a/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt +++ b/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt @@ -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)) } diff --git a/compiler/daemon/src/org/jetbrains/kotlin/daemon/RemoteEnumWhenTracker.kt b/compiler/daemon/src/org/jetbrains/kotlin/daemon/RemoteEnumWhenTracker.kt new file mode 100644 index 00000000000..5ebd2ffd6a3 --- /dev/null +++ b/compiler/daemon/src/org/jetbrains/kotlin/daemon/RemoteEnumWhenTracker.kt @@ -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) + } + } +} \ No newline at end of file diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt index 8e24ae821cc..d4657c348f9 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt @@ -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) + ) + } } /* diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactory.kt index 0558e43a087..c453340e165 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactory.kt @@ -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, 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, 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) diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/IncrementalPassThroughEnumWhenTrackerComponent.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/IncrementalPassThroughEnumWhenTrackerComponent.kt new file mode 100644 index 00000000000..3057b092646 --- /dev/null +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/IncrementalPassThroughEnumWhenTrackerComponent.kt @@ -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) + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt index 464a3f46010..569d90e8076 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt @@ -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 } diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/FirEnumWhenTrackerComponent.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/FirEnumWhenTrackerComponent.kt new file mode 100644 index 00000000000..4c7d864e9ff --- /dev/null +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/FirEnumWhenTrackerComponent.kt @@ -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) +} \ No newline at end of file diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt index b9d3344f908..ea0ff5adb42 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt @@ -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) diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmResolverForModuleFactory.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmResolverForModuleFactory.kt index bc8a107ba02..7d0a695c94e 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmResolverForModuleFactory.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmResolverForModuleFactory.kt @@ -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, diff --git a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt index 035cbc67f13..180cb8f1791 100644 --- a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt +++ b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt @@ -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 { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt index 69b753c35eb..00a5b296e12 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt @@ -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 } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt b/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt index 0edf59d340f..350c4b1b956 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt @@ -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() } -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() diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ControlFlowAnalyzer.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ControlFlowAnalyzer.java index 9652a7cc513..b23e2878ed1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ControlFlowAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ControlFlowAnalyzer.java @@ -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(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorDispatcher.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorDispatcher.java index ddf001aedb0..5e4c5993fbc 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorDispatcher.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingVisitorDispatcher.java @@ -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, 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()) diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/targets/KotlinJvmModuleBuildTarget.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/targets/KotlinJvmModuleBuildTarget.kt index 928585e070f..63a598fbc2f 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/targets/KotlinJvmModuleBuildTarget.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/targets/KotlinJvmModuleBuildTarget.kt @@ -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, 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> = chunk.targets.keysToMap { val files = HashSet() @@ -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) + } } \ No newline at end of file diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/targets/KotlinModuleBuildTarget.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/targets/KotlinModuleBuildTarget.kt index 6ae8e2a6b8a..d470e96a263 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/targets/KotlinModuleBuildTarget.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/targets/KotlinModuleBuildTarget.kt @@ -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 intern incrementalCaches: Map, 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 intern } }) register(InlineConstTracker::class.java, inlineConstTracker) + register(EnumWhenTracker::class.java, enumWhenTracker) } } diff --git a/jps/jps-plugin/testData/incremental/withJava/javaUsedInKotlin/enumEntryAdded/build.log b/jps/jps-plugin/testData/incremental/withJava/javaUsedInKotlin/enumEntryAdded/build.log index f9695c15cb5..a338aff88a9 100644 --- a/jps/jps-plugin/testData/incremental/withJava/javaUsedInKotlin/enumEntryAdded/build.log +++ b/jps/jps-plugin/testData/incremental/withJava/javaUsedInKotlin/enumEntryAdded/build.log @@ -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 \ No newline at end of file diff --git a/js/js.frontend/src/org/jetbrains/kotlin/frontend/js/di/injection.kt b/js/js.frontend/src/org/jetbrains/kotlin/frontend/js/di/injection.kt index 916aa81a1a5..aa8d563fb7a 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/frontend/js/di/injection.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/frontend/js/di/injection.kt @@ -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, 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, targetEnvironment: TargetEnvironment, ): LazyTopDownAnalyzer { return createContainerForJS( moduleContext, bindingTrace, declarationProviderFactory, languageVersionSettings, - lookupTracker, expectActualTracker, inlineConstTracker, additionalPackages, targetEnvironment + lookupTracker, expectActualTracker, inlineConstTracker, enumWhenTracker, additionalPackages, targetEnvironment ).get() } diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt index 69b7687e985..0ce3b623c72 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt @@ -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, ) diff --git a/plugins/scripting/scripting-compiler-js/src/org/jetbrains/kotlin/scripting/js/AbstractJsScriptlikeCodeAnalyser.kt b/plugins/scripting/scripting-compiler-js/src/org/jetbrains/kotlin/scripting/js/AbstractJsScriptlikeCodeAnalyser.kt index a954be0a8c0..7a9e33d3f94 100644 --- a/plugins/scripting/scripting-compiler-js/src/org/jetbrains/kotlin/scripting/js/AbstractJsScriptlikeCodeAnalyser.kt +++ b/plugins/scripting/scripting-compiler-js/src/org/jetbrains/kotlin/scripting/js/AbstractJsScriptlikeCodeAnalyser.kt @@ -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() val moduleDescriptor = moduleContext.module @@ -68,6 +70,7 @@ abstract class AbstractJsScriptlikeCodeAnalyser( lookupTracker, expectActualTracker, inlineConstTracker, + enumWhenTracker, additionalPackages, CompilerEnvironment, )