From 68af7056642048bb0855d31aa6b5d0ce1953ebd0 Mon Sep 17 00:00:00 2001 From: "Aleksei.Cherepanov" Date: Fri, 11 Aug 2023 15:17:50 +0200 Subject: [PATCH] Add import tracker This tracker reports import directives to IJ's JPS to track changes and detectwehen it is needed to adjust compilation scope. #KT-44835 Fixed --- .../kotlin/incremental/ImportTrackerImpl.kt | 21 +++++++++++++++ .../cli/common/FirSessionConstructionUtils.kt | 2 ++ .../jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt | 7 +++-- .../kotlin/config/CommonConfigurationKeys.kt | 8 +++--- .../CompilerCallbackServicesFacadeServer.kt | 7 +++++ .../common/CompilerCallbackServicesFacade.kt | 8 ++++++ .../fir/session/ComponentsContainers.kt | 9 ++++++- .../fir/session/FirAbstractSessionFactory.kt | 4 ++- .../fir/session/FirCommonSessionFactory.kt | 3 +++ .../kotlin/fir/session/FirJsSessionFactory.kt | 1 + .../fir/session/FirJvmSessionFactory.kt | 3 +++ .../fir/session/FirNativeSessionFactory.kt | 1 + .../fir/session/FirSessionFactoryHelper.kt | 3 +++ .../fir/session/FirWasmSessionFactory.kt | 1 + ...mentalPassThroughImportTrackerComponent.kt | 16 +++++++++++ .../kotlin/fir/scopes/ImportingScopes.kt | 11 +++++++- .../kotlin/fir/FirImportTrackerComponent.kt | 17 ++++++++++++ .../fir/AbstractFirBaseDiagnosticsTest.kt | 1 + .../kotlin/fir/FirTestSessionFactoryHelper.kt | 2 ++ .../incremental/components/ImportTracker.kt | 26 ++++++++++++++++++ .../JpsCompilerServicesFacadeImpl.kt | 6 ++--- .../kotlin/jps/build/KotlinBuilder.kt | 17 +++++++----- .../jps/targets/KotlinJsModuleBuildTarget.kt | 10 +++---- .../jps/targets/KotlinJvmModuleBuildTarget.kt | 27 ++++++++++--------- .../jps/targets/KotlinModuleBuildTarget.kt | 9 +++---- 25 files changed, 175 insertions(+), 45 deletions(-) create mode 100644 build-common/src/org/jetbrains/kotlin/incremental/ImportTrackerImpl.kt create mode 100644 compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/IncrementalPassThroughImportTrackerComponent.kt create mode 100644 compiler/fir/semantics/src/org/jetbrains/kotlin/fir/FirImportTrackerComponent.kt create mode 100644 core/compiler.common/src/org/jetbrains/kotlin/incremental/components/ImportTracker.kt diff --git a/build-common/src/org/jetbrains/kotlin/incremental/ImportTrackerImpl.kt b/build-common/src/org/jetbrains/kotlin/incremental/ImportTrackerImpl.kt new file mode 100644 index 00000000000..325d55229f2 --- /dev/null +++ b/build-common/src/org/jetbrains/kotlin/incremental/ImportTrackerImpl.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.incremental + +import org.jetbrains.kotlin.incremental.components.ImportTracker +import java.util.concurrent.ConcurrentHashMap + +@Suppress("unused") +class ImportTrackerImpl: ImportTracker { + private val filePathToImportedFqNames = ConcurrentHashMap>() + + val filePathToImportedFqNamesMap: Map> + get() = filePathToImportedFqNames + + override fun report(filePath: String, importedFqName: String) { + filePathToImportedFqNames.getOrPut(filePath) { hashSetOf() }.add(importedFqName) + } +} \ No newline at end of file diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/FirSessionConstructionUtils.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/FirSessionConstructionUtils.kt index 9096bfed94c..eeeea768883 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/FirSessionConstructionUtils.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/FirSessionConstructionUtils.kt @@ -100,6 +100,7 @@ fun prepareJvmSessions( configuration.languageVersionSettings, configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER), configuration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER), + configuration.get(CommonConfigurationKeys.IMPORT_TRACKER), needRegisterJavaElementFinder = true, registerExtraComponents = {}, sessionConfigurator, @@ -293,6 +294,7 @@ fun prepareCommonSessions( configuration.languageVersionSettings, lookupTracker = configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER), enumWhenTracker = configuration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER), + importTracker = configuration.get(CommonConfigurationKeys.IMPORT_TRACKER), registerExtraComponents = {}, init = sessionConfigurator ) 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 81c58eaceb9..0cea42772b6 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt @@ -38,10 +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 +import org.jetbrains.kotlin.incremental.components.* import org.jetbrains.kotlin.load.java.JavaClassesTracker import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion @@ -225,6 +222,8 @@ class K2JVMCompiler : CLICompiler() { putIfNotNull(CommonConfigurationKeys.ENUM_WHEN_TRACKER, services[EnumWhenTracker::class.java]) + putIfNotNull(CommonConfigurationKeys.IMPORT_TRACKER, services[ImportTracker::class.java]) + putIfNotNull( JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS, services[IncrementalCompilationComponents::class.java] diff --git a/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt b/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt index afd8e3225a2..f9b4346d3db 100644 --- a/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt +++ b/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt @@ -17,10 +17,7 @@ package org.jetbrains.kotlin.config import org.jetbrains.kotlin.constant.EvaluatedConstTracker -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 +import org.jetbrains.kotlin.incremental.components.* import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion object CommonConfigurationKeys { @@ -48,6 +45,9 @@ object CommonConfigurationKeys { @JvmField val ENUM_WHEN_TRACKER = CompilerConfigurationKey.create("enum when tracker") + @JvmField + val IMPORT_TRACKER = CompilerConfigurationKey.create("import 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 16ed5902b82..957bbbb2c42 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 @@ -36,6 +36,7 @@ open class CompilerCallbackServicesFacadeServer( val expectActualTracker: ExpectActualTracker? = null, val inlineConstTracker: InlineConstTracker? = null, val enumWhenTracker: EnumWhenTracker? = null, + val importTracker: ImportTracker? = null, val incrementalResultsConsumer: IncrementalResultsConsumer? = null, val incrementalDataProvider: IncrementalDataProvider? = null, port: Int = SOCKET_ANY_FREE_PORT @@ -57,6 +58,8 @@ open class CompilerCallbackServicesFacadeServer( override fun hasEnumWhenTracker(): Boolean = enumWhenTracker != null + override fun hasImportTracker(): Boolean = importTracker != null + override fun hasIncrementalResultsConsumer(): Boolean = incrementalResultsConsumer != null override fun hasIncrementalDataProvider(): Boolean = incrementalDataProvider != null @@ -128,6 +131,10 @@ open class CompilerCallbackServicesFacadeServer( enumWhenTracker?.report(whenUsageClassPath, enumClassFqName) ?: throw NullPointerException("enumWhenTracker was not initialized") } + override fun importTracker_report(filePath: String, importedFqName: String) { + importTracker?.report(filePath, importedFqName) ?: throw NullPointerException("importTracker 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 bae65e7443a..29155cab33b 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 @@ -54,6 +54,9 @@ interface CompilerCallbackServicesFacade : Remote { @Throws(RemoteException::class) fun hasEnumWhenTracker(): Boolean + @Throws(RemoteException::class) + fun hasImportTracker(): Boolean + @Throws(RemoteException::class) fun hasIncrementalResultsConsumer(): Boolean @@ -117,6 +120,11 @@ interface CompilerCallbackServicesFacade : Remote { @Throws(RemoteException::class) fun enumWhenTracker_report(whenUsageClassPath: String, enumClassFqName: String) + // --------------------------------------------------- + // ImportTracker + @Throws(RemoteException::class) + fun importTracker_report(filePath: String, importedFqName: String) + // --------------------------------------------------- // IncrementalResultsConsumer (js) @Throws(RemoteException::class) 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 3d367d9dcc4..cd1b3cafec7 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 @@ -53,6 +53,7 @@ import org.jetbrains.kotlin.fir.serialization.FirProvidedDeclarationsForMetadata import org.jetbrains.kotlin.fir.symbols.FirLazyDeclarationResolver import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.incremental.components.EnumWhenTracker +import org.jetbrains.kotlin.incremental.components.ImportTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.resolve.jvm.JvmTypeSpecificityComparator import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver @@ -123,7 +124,7 @@ fun FirSession.registerCommonJavaComponents(javaModuleResolver: JavaModuleResolv * Resolve components which are same on all platforms */ @OptIn(SessionConfiguration::class) -fun FirSession.registerResolveComponents(lookupTracker: LookupTracker? = null, enumWhenTracker: EnumWhenTracker? = null) { +fun FirSession.registerResolveComponents(lookupTracker: LookupTracker? = null, enumWhenTracker: EnumWhenTracker? = null, importTracker: ImportTracker? = null) { register(FirQualifierResolver::class, FirQualifierResolverImpl(this)) register(FirTypeResolver::class, FirTypeResolverImpl(this)) register(CheckersComponent::class, CheckersComponent()) @@ -145,6 +146,12 @@ fun FirSession.registerResolveComponents(lookupTracker: LookupTracker? = null, e IncrementalPassThroughEnumWhenTrackerComponent(enumWhenTracker) ) } + if (importTracker != null) { + register( + FirImportTrackerComponent::class, + IncrementalPassThroughImportTrackerComponent(importTracker) + ) + } register(FirExpectActualMatchingContextFactory::class, FirExpectActualMatchingContextImpl.Factory) } diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirAbstractSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirAbstractSessionFactory.kt index 810a2e8a968..a13f25b1350 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirAbstractSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirAbstractSessionFactory.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.incremental.components.EnumWhenTracker +import org.jetbrains.kotlin.incremental.components.ImportTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.name.Name @@ -83,6 +84,7 @@ abstract class FirAbstractSessionFactory { languageVersionSettings: LanguageVersionSettings, lookupTracker: LookupTracker?, enumWhenTracker: EnumWhenTracker?, + importTracker: ImportTracker?, init: FirSessionConfigurator.() -> Unit, registerExtraComponents: ((FirSession) -> Unit), registerExtraCheckers: ((FirSessionConfigurator) -> Unit)?, @@ -99,7 +101,7 @@ abstract class FirAbstractSessionFactory { registerModuleData(moduleData) registerCliCompilerOnlyComponents() registerCommonComponents(languageVersionSettings) - registerResolveComponents(lookupTracker, enumWhenTracker) + registerResolveComponents(lookupTracker, enumWhenTracker, importTracker) registerExtraComponents(this) val kotlinScopeProvider = createKotlinScopeProvider.invoke() diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirCommonSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirCommonSessionFactory.kt index 69deec96dba..4a26b0b85f6 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirCommonSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirCommonSessionFactory.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.scopes.FirPlatformClassMapper 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.ImportTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary import org.jetbrains.kotlin.load.kotlin.PackageAndMetadataPartProvider @@ -91,6 +92,7 @@ object FirCommonSessionFactory : FirAbstractSessionFactory() { languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT, lookupTracker: LookupTracker? = null, enumWhenTracker: EnumWhenTracker? = null, + importTracker: ImportTracker? = null, registerExtraComponents: ((FirSession) -> Unit) = {}, init: FirSessionConfigurator.() -> Unit = {} ): FirSession { @@ -101,6 +103,7 @@ object FirCommonSessionFactory : FirAbstractSessionFactory() { languageVersionSettings, lookupTracker, enumWhenTracker, + importTracker, init, registerExtraComponents = { it.register(FirVisibilityChecker::class, FirVisibilityChecker.Default) diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJsSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJsSessionFactory.kt index d337c962cd7..508c9e479d1 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJsSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJsSessionFactory.kt @@ -52,6 +52,7 @@ object FirJsSessionFactory : FirAbstractSessionFactory() { compilerConfiguration.languageVersionSettings, lookupTracker, null, + null, init, registerExtraComponents = { session -> session.registerJsSpecificComponents(compilerConfiguration) diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJvmSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJvmSessionFactory.kt index fbee8280d46..2a7930eafed 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJvmSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJvmSessionFactory.kt @@ -27,6 +27,7 @@ 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.ImportTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.load.kotlin.PackagePartProvider import org.jetbrains.kotlin.name.Name @@ -89,6 +90,7 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() { languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT, lookupTracker: LookupTracker? = null, enumWhenTracker: EnumWhenTracker? = null, + importTracker: ImportTracker? = null, needRegisterJavaElementFinder: Boolean, registerExtraComponents: ((FirSession) -> Unit) = {}, init: FirSessionConfigurator.() -> Unit = {} @@ -100,6 +102,7 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() { languageVersionSettings, lookupTracker, enumWhenTracker, + importTracker, init, registerExtraComponents = { it.registerCommonJavaComponents(projectEnvironment.getJavaModuleResolver()) diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirNativeSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirNativeSessionFactory.kt index 80ab05f9784..b377f4c064f 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirNativeSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirNativeSessionFactory.kt @@ -75,6 +75,7 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() { languageVersionSettings, null, null, + null, init, registerExtraComponents = { it.register(FirVisibilityChecker::class, FirVisibilityChecker.Default) diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactoryHelper.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactoryHelper.kt index a6325f807c2..73f7319a057 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactoryHelper.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactoryHelper.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider 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.ImportTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.platform.TargetPlatform @@ -33,6 +34,7 @@ object FirSessionFactoryHelper { librariesScope: AbstractProjectFileSearchScope, lookupTracker: LookupTracker?, enumWhenTracker: EnumWhenTracker?, + importTracker: ImportTracker?, incrementalCompilationContext: IncrementalCompilationContext?, extensionRegistrars: List, needRegisterJavaElementFinder: Boolean, @@ -73,6 +75,7 @@ object FirSessionFactoryHelper { languageVersionSettings, lookupTracker, enumWhenTracker, + importTracker, needRegisterJavaElementFinder, registerExtraComponents = {}, sessionConfigurator, diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirWasmSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirWasmSessionFactory.kt index db85ba116f8..f7bb5328b2b 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirWasmSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirWasmSessionFactory.kt @@ -44,6 +44,7 @@ object FirWasmSessionFactory : FirAbstractSessionFactory() { languageVersionSettings, lookupTracker, null, + null, init, registerExtraComponents = { session -> session.registerWasmSpecificComponents() diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/IncrementalPassThroughImportTrackerComponent.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/IncrementalPassThroughImportTrackerComponent.kt new file mode 100644 index 00000000000..67cac762457 --- /dev/null +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/IncrementalPassThroughImportTrackerComponent.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.FirImportTrackerComponent +import org.jetbrains.kotlin.incremental.components.ImportTracker + + +class IncrementalPassThroughImportTrackerComponent(private val importTracker: ImportTracker) : FirImportTrackerComponent() { + override fun report(filePath: String, importedFqName: String) { + importTracker.report(filePath, importedFqName) + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/ImportingScopes.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/ImportingScopes.kt index 487c93eddf9..8ee04394f0e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/ImportingScopes.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/ImportingScopes.kt @@ -8,7 +8,9 @@ package org.jetbrains.kotlin.fir.scopes import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirResolvePhase +import org.jetbrains.kotlin.fir.importTracker import org.jetbrains.kotlin.fir.packageFqName +import org.jetbrains.kotlin.fir.reportImportDirectives import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.scopeSessionKey import org.jetbrains.kotlin.fir.scopes.impl.* @@ -18,13 +20,14 @@ import org.jetbrains.kotlin.name.FqName private val ALL_IMPORTS = scopeSessionKey() private val DEFAULT_STAR_IMPORT = scopeSessionKey() private val DEFAULT_SIMPLE_IMPORT = scopeSessionKey() + private data class DefaultStarImportKey(val priority: DefaultImportPriority, val excludedImportNames: Set) fun createImportingScopes( file: FirFile, session: FirSession, scopeSession: ScopeSession, - useCaching: Boolean = true + useCaching: Boolean = true, ): List = if (useCaching) { scopeSession.getOrBuild(file, ALL_IMPORTS) { ListStorageFirScope(computeImportingScopes(file, session, scopeSession)) @@ -49,6 +52,12 @@ internal fun computeImportingScopes( if (it.parent() == file.packageFqName) it.shortName() else null } + session.importTracker?.let { tracker -> + file.imports.map { import -> + tracker.reportImportDirectives(file.sourceFile?.path, import.importedFqName?.asString()) + } + } + return buildList { if (includeDefaultImports) { this += FirDefaultStarImportingScope( diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/FirImportTrackerComponent.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/FirImportTrackerComponent.kt new file mode 100644 index 00000000000..0f7ef21e320 --- /dev/null +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/FirImportTrackerComponent.kt @@ -0,0 +1,17 @@ +/* + * 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 + +abstract class FirImportTrackerComponent : FirSessionComponent { + abstract fun report(filePath: String, importedFqName: String) +} + +val FirSession.importTracker: FirImportTrackerComponent? by FirSession.nullableSessionComponentAccessor() + +fun FirImportTrackerComponent.reportImportDirectives(filePath: String?, importedFqName: String?) { + if (filePath == null || importedFqName == null) return + this.report(filePath, importedFqName) +} \ No newline at end of file diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirBaseDiagnosticsTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirBaseDiagnosticsTest.kt index 454db000dab..9546deeae07 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirBaseDiagnosticsTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirBaseDiagnosticsTest.kt @@ -99,6 +99,7 @@ abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() { librariesScope = PsiBasedProjectFileSearchScope(allProjectScope), lookupTracker = null, enumWhenTracker = null, + importTracker = null, incrementalCompilationContext = null, extensionRegistrars = emptyList(), needRegisterJavaElementFinder = true diff --git a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/FirTestSessionFactoryHelper.kt b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/FirTestSessionFactoryHelper.kt index ffb7c17244a..ed93247dd55 100644 --- a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/FirTestSessionFactoryHelper.kt +++ b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/FirTestSessionFactoryHelper.kt @@ -43,6 +43,7 @@ object FirTestSessionFactoryHelper { librariesScope, lookupTracker = null, enumWhenTracker = null, + importTracker = null, incrementalCompilationContext = null, extensionRegistrars = emptyList(), needRegisterJavaElementFinder = true, @@ -75,6 +76,7 @@ object FirTestSessionFactoryHelper { PsiBasedProjectFileSearchScope(librariesScope), lookupTracker = null, enumWhenTracker = null, + importTracker = null, incrementalCompilationContext = null, extensionRegistrars = emptyList(), needRegisterJavaElementFinder = true, diff --git a/core/compiler.common/src/org/jetbrains/kotlin/incremental/components/ImportTracker.kt b/core/compiler.common/src/org/jetbrains/kotlin/incremental/components/ImportTracker.kt new file mode 100644 index 00000000000..82a1fe7294f --- /dev/null +++ b/core/compiler.common/src/org/jetbrains/kotlin/incremental/components/ImportTracker.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.incremental.components + +import org.jetbrains.kotlin.container.DefaultImplementation + +/** + * ImportTracker is used to track imports directives used in Kotlin for correct build scope expansion in IC during JPS build. + * e.g. Removing of Java file, that Kotlin relies on by importing + */ +@DefaultImplementation(ImportTracker.DoNothing::class) +interface ImportTracker { + + /** + * Report import directives, where FqName is [importedFqName]. + * Format of [importedFqName] class is "package.Outer.Inner" + */ + fun report(filePath: String, importedFqName: String) + + object DoNothing : ImportTracker { + override fun report(filePath: String, importedFqName: String) {} + } +} \ No newline at end of file diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsCompilerServicesFacadeImpl.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsCompilerServicesFacadeImpl.kt index 2864ce872cb..50917d9a955 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsCompilerServicesFacadeImpl.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/compilerRunner/JpsCompilerServicesFacadeImpl.kt @@ -20,10 +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 +import org.jetbrains.kotlin.incremental.components.* import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents @@ -40,6 +37,7 @@ internal class JpsCompilerServicesFacadeImpl( env.services[ExpectActualTracker::class.java], env.services[InlineConstTracker::class.java], env.services[EnumWhenTracker::class.java], + env.services[ImportTracker::class.java], env.services[IncrementalResultsConsumer::class.java], env.services[IncrementalDataProvider::class.java], port diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt index c4aa99c7215..e587c4a12fa 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt @@ -35,10 +35,7 @@ import org.jetbrains.kotlin.config.KotlinModuleKind import org.jetbrains.kotlin.config.Services import org.jetbrains.kotlin.daemon.common.isDaemonEnabled 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 +import org.jetbrains.kotlin.incremental.components.* import org.jetbrains.kotlin.jps.KotlinJpsBundle import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache import org.jetbrains.kotlin.jps.incremental.JpsLookupStorageManager @@ -245,6 +242,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { ExpectActualTracker.DoNothing, InlineConstTracker.DoNothing, EnumWhenTracker.DoNothing, + ImportTracker.DoNothing, chunk, messageCollector ) ?: return @@ -420,18 +418,21 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { val project = projectDescriptor.project val lookupTracker = getLookupTracker(project, representativeTarget) - val exceptActualTracer = ExpectActualTrackerImpl() + val exceptActualTracker = ExpectActualTrackerImpl() val incrementalCaches = kotlinChunk.loadCaches() val inlineConstTracker = InlineConstTrackerImpl() val enumWhenTracker = EnumWhenTrackerImpl() + val importTracker = ImportTrackerImpl() + val environment = createCompileEnvironment( context, representativeTarget, incrementalCaches, lookupTracker, - exceptActualTracer, + exceptActualTracker, inlineConstTracker, enumWhenTracker, + importTracker, chunk, messageCollector ) ?: return ABORT @@ -625,6 +626,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { exceptActualTracer: ExpectActualTracker, inlineConstTracker: InlineConstTracker, enumWhenTracker: EnumWhenTracker, + importTracker: ImportTracker, chunk: ModuleChunk, messageCollector: MessageCollectorAdapter ): JpsCompilerEnvironment? { @@ -635,7 +637,8 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) { lookupTracker, exceptActualTracer, inlineConstTracker, - enumWhenTracker + enumWhenTracker, + importTracker ) build() } diff --git a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/targets/KotlinJsModuleBuildTarget.kt b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/targets/KotlinJsModuleBuildTarget.kt index 927917973cd..e91e10d7506 100644 --- a/jps/jps-plugin/src/org/jetbrains/kotlin/jps/targets/KotlinJsModuleBuildTarget.kt +++ b/jps/jps-plugin/src/org/jetbrains/kotlin/jps/targets/KotlinJsModuleBuildTarget.kt @@ -20,10 +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 +import org.jetbrains.kotlin.incremental.components.* import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider import org.jetbrains.kotlin.incremental.js.IncrementalDataProviderFromCache import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer @@ -72,9 +69,10 @@ class KotlinJsModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleBu lookupTracker: LookupTracker, exceptActualTracer: ExpectActualTracker, inlineConstTracker: InlineConstTracker, - enumWhenTracker: EnumWhenTracker + enumWhenTracker: EnumWhenTracker, + importTracker: ImportTracker ) { - super.makeServices(builder, incrementalCaches, lookupTracker, exceptActualTracer, inlineConstTracker, enumWhenTracker) + super.makeServices(builder, incrementalCaches, lookupTracker, exceptActualTracer, inlineConstTracker, enumWhenTracker, importTracker) 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 af2a1b70752..9c6145e2371 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 @@ -11,6 +11,7 @@ import com.intellij.util.io.URLUtil import org.jetbrains.jps.ModuleChunk import org.jetbrains.jps.builders.java.JavaBuilderUtil import org.jetbrains.jps.builders.java.dependencyView.Callbacks +import org.jetbrains.jps.builders.java.dependencyView.Callbacks.Backend import org.jetbrains.jps.builders.storage.BuildDataPaths import org.jetbrains.jps.incremental.* import org.jetbrains.jps.model.java.JpsJavaExtensionService @@ -27,10 +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 +import org.jetbrains.kotlin.incremental.components.* import org.jetbrains.kotlin.jps.build.KotlinBuilder import org.jetbrains.kotlin.jps.build.KotlinCompileContext import org.jetbrains.kotlin.jps.build.KotlinDirtySourceFilesHolder @@ -81,9 +79,10 @@ class KotlinJvmModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleB lookupTracker: LookupTracker, exceptActualTracer: ExpectActualTracker, inlineConstTracker: InlineConstTracker, - enumWhenTracker: EnumWhenTracker + enumWhenTracker: EnumWhenTracker, + importTracker: ImportTracker ) { - super.makeServices(builder, incrementalCaches, lookupTracker, exceptActualTracer, inlineConstTracker, enumWhenTracker) + super.makeServices(builder, incrementalCaches, lookupTracker, exceptActualTracer, inlineConstTracker, enumWhenTracker, importTracker) with(builder) { register( @@ -365,6 +364,7 @@ class KotlinJvmModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleB val callback = JavaBuilderUtil.getDependenciesRegistrar(localContext) val inlineConstTracker = environment.services[InlineConstTracker::class.java] as InlineConstTrackerImpl val enumWhenTracker = environment.services[EnumWhenTracker::class.java] as EnumWhenTrackerImpl + val importTracker = environment.services[ImportTracker::class.java] as ImportTrackerImpl val targetDirtyFiles: Map> = chunk.targets.keysToMap { val files = HashSet() @@ -393,10 +393,10 @@ class KotlinJvmModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleB sourceFiles.removeAll(targetDirtyFiles[target] ?: emptySet()) sourceFiles.addAll(output.sourceFiles) - // process inlineConstTracker + // process trackers for (sourceFile: File in sourceFiles) { processInlineConstTracker(inlineConstTracker, sourceFile, output, callback) - processEnumWhenTracker(enumWhenTracker, sourceFile, output, callback) + processBothEnumWhenAndImportTrackers(enumWhenTracker, importTracker, sourceFile, output, callback) } callback.associate( @@ -412,7 +412,7 @@ class KotlinJvmModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleB JavaBuilderUtil.registerSuccessfullyCompiled(localContext, allCompiled) } - private fun processInlineConstTracker(inlineConstTracker: InlineConstTrackerImpl, sourceFile: File, output: GeneratedJvmClass, callback: Callbacks.Backend) { + private fun processInlineConstTracker(inlineConstTracker: InlineConstTrackerImpl, sourceFile: File, output: GeneratedJvmClass, callback: Backend) { val cRefs = inlineConstTracker.inlineConstMap[sourceFile.path]?.mapNotNull { cRef: ConstantRef -> val descriptor = when (cRef.constType) { "Byte" -> "B" @@ -433,8 +433,11 @@ class KotlinJvmModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleB 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) + private fun processBothEnumWhenAndImportTrackers(enumWhenTracker: EnumWhenTrackerImpl, importTracker: ImportTrackerImpl, sourceFile: File, output: GeneratedJvmClass, callback: Backend) { + val enumFqNameClasses = enumWhenTracker.whenExpressionFilePathToEnumClassMap[sourceFile.path]?.map { "$it.*" } + val importedFqNames = importTracker.filePathToImportedFqNamesMap[sourceFile.path] + if (enumFqNameClasses == null && importedFqNames == null) return + + callback.registerImports(output.outputClass.className.internalName, importedFqNames ?: listOf(), enumFqNameClasses ?: listOf()) } } \ 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 0a16ab14f47..1a44fdf4ac6 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 @@ -22,10 +22,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 +import org.jetbrains.kotlin.incremental.components.* import org.jetbrains.kotlin.jps.KotlinJpsBundle import org.jetbrains.kotlin.jps.build.* import org.jetbrains.kotlin.jps.incremental.CacheAttributesDiff @@ -272,7 +269,8 @@ abstract class KotlinModuleBuildTarget intern lookupTracker: LookupTracker, exceptActualTracer: ExpectActualTracker, inlineConstTracker: InlineConstTracker, - enumWhenTracker: EnumWhenTracker + enumWhenTracker: EnumWhenTracker, + importTracker: ImportTracker ) { with(builder) { register(LookupTracker::class.java, lookupTracker) @@ -284,6 +282,7 @@ abstract class KotlinModuleBuildTarget intern }) register(InlineConstTracker::class.java, inlineConstTracker) register(EnumWhenTracker::class.java, enumWhenTracker) + register(ImportTracker::class.java, importTracker) } }