[CLI] Store information about HMPP module for source files

This commit is contained in:
Dmitriy Novozhilov
2023-02-09 17:48:11 +02:00
committed by Space Team
parent 77caa31640
commit d4bb740a62
16 changed files with 68 additions and 24 deletions
@@ -200,8 +200,9 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
val commonSourcesArray = arguments.commonSources
val commonSources = commonSourcesArray?.toSet() ?: emptySet()
val hmppCliModuleStructure = configuration.get(CommonConfigurationKeys.HMPP_MODULE_STRUCTURE)
for (arg in arguments.freeArgs) {
configuration.addKotlinSourceRoot(arg, commonSources.contains(arg))
configuration.addKotlinSourceRoot(arg, commonSources.contains(arg), hmppCliModuleStructure?.getModuleNameForSource(arg))
}
arguments.relativePathBases?.let {
@@ -13,11 +13,11 @@ interface ContentRoot
/**
* @param isCommon whether this source root contains sources of a common module in a multi-platform project
*/
data class KotlinSourceRoot(val path: String, val isCommon: Boolean): ContentRoot
data class KotlinSourceRoot(val path: String, val isCommon: Boolean, val hmppModuleName: String?): ContentRoot
@JvmOverloads
fun CompilerConfiguration.addKotlinSourceRoot(path: String, isCommon: Boolean = false) {
add(CLIConfigurationKeys.CONTENT_ROOTS, KotlinSourceRoot(path, isCommon))
fun CompilerConfiguration.addKotlinSourceRoot(path: String, isCommon: Boolean = false, hmppModuleName: String? = null) {
add(CLIConfigurationKeys.CONTENT_ROOTS, KotlinSourceRoot(path, isCommon, hmppModuleName))
}
fun CompilerConfiguration.addKotlinSourceRoots(sources: List<String>): Unit =
@@ -292,7 +292,7 @@ class KotlinCoreEnvironment private constructor(
}
fun addKotlinSourceRoots(rootDirs: List<File>) {
val roots = rootDirs.map { KotlinSourceRoot(it.absolutePath, isCommon = false) }
val roots = rootDirs.map { KotlinSourceRoot(it.absolutePath, isCommon = false, hmppModuleName = null) }
sourceFiles += createSourceFilesFromSourceRoots(configuration, project, roots).toSet() - sourceFiles
}
@@ -376,11 +376,12 @@ object KotlinToJVMBytecodeCompiler {
}
fun CompilerConfiguration.configureSourceRoots(chunk: List<Module>, buildFile: File? = null) {
val hmppCliModuleStructure = get(CommonConfigurationKeys.HMPP_MODULE_STRUCTURE)
for (module in chunk) {
val commonSources = getBuildFilePaths(buildFile, module.getCommonSourceFiles()).toSet()
for (path in getBuildFilePaths(buildFile, module.getSourceFiles())) {
addKotlinSourceRoot(path, isCommon = path in commonSources)
addKotlinSourceRoot(path, isCommon = path in commonSources, hmppCliModuleStructure?.getModuleNameForSource(path))
}
}
@@ -25,8 +25,8 @@ import org.jetbrains.kotlin.extensions.CompilerConfigurationExtension
import org.jetbrains.kotlin.extensions.PreprocessedFileCreator
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.modules.Module
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.multiplatform.hmppModuleName
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
import java.io.File
@@ -38,7 +38,7 @@ inline fun List<KotlinSourceRoot>.forAllFiles(
configuration: CompilerConfiguration,
project: Project,
reportLocation: CompilerMessageLocation? = null,
body: (VirtualFile, Boolean) -> Unit
body: (VirtualFile, Boolean, moduleName: String?) -> Unit
) {
val localFileSystem = VirtualFileManager.getInstance()
.getFileSystem(StandardFileSystems.FILE_PROTOCOL)
@@ -49,7 +49,7 @@ inline fun List<KotlinSourceRoot>.forAllFiles(
var pluginsConfigured = false
for ((sourceRootPath, isCommon) in this) {
for ((sourceRootPath, isCommon, hmppModuleName) in this) {
val sourceRoot = File(sourceRootPath)
val vFile = localFileSystem.findFileByPath(sourceRoot.normalize().path)
if (vFile == null) {
@@ -85,7 +85,7 @@ inline fun List<KotlinSourceRoot>.forAllFiles(
virtualFile.registerPluginsSuppliedExtensionsIfNeeded(project)
pluginsConfigured = true
}
body(virtualFile, isCommon)
body(virtualFile, isCommon, hmppModuleName)
}
}
}
@@ -112,10 +112,13 @@ fun createSourceFilesFromSourceRoots(
): MutableList<KtFile> {
val psiManager = PsiManager.getInstance(project)
val result = mutableListOf<KtFile>()
sourceRoots.forAllFiles(configuration, project, reportLocation) { virtualFile, isCommon ->
sourceRoots.forAllFiles(configuration, project, reportLocation) { virtualFile, isCommon, moduleName ->
psiManager.findFile(virtualFile)?.let {
if (it is KtFile) {
it.isCommonSource = isCommon
if (moduleName != null) {
it.hmppModuleName = moduleName
}
result.add(it)
}
}
@@ -104,12 +104,13 @@ fun compileModulesUsingFrontendIrAndLightTree(
val moduleConfiguration = compilerConfiguration.copy().applyModuleProperties(module, buildFile).apply {
put(JVMConfigurationKeys.FRIEND_PATHS, module.getFriendPaths())
}
val (platformSources, commonSources) = collectSources(compilerConfiguration, projectEnvironment, messageCollector)
val (platformSources, commonSources, sourcesByModuleName) = collectSources(compilerConfiguration, projectEnvironment, messageCollector)
val compilerInput = ModuleCompilerInput(
TargetId(module),
CommonPlatforms.defaultCommonPlatform, commonSources,
JvmPlatforms.unspecifiedJvmPlatform, platformSources,
sourcesByModuleName,
moduleConfiguration
)
@@ -169,26 +170,40 @@ fun compileModulesUsingFrontendIrAndLightTree(
)
}
data class GroupedKtSources(
val platformSources: Set<KtSourceFile>,
val commonSources: Set<KtSourceFile>,
val sourcesByModuleName: Map<String, Set<KtSourceFile>>,
)
fun collectSources(
compilerConfiguration: CompilerConfiguration,
projectEnvironment: VfsBasedProjectEnvironment,
messageCollector: MessageCollector
): Pair<LinkedHashSet<KtSourceFile>, LinkedHashSet<KtSourceFile>> {
): GroupedKtSources {
val platformSources = linkedSetOf<KtSourceFile>()
val commonSources = linkedSetOf<KtSourceFile>()
val sourcesByModuleName = mutableMapOf<String, MutableSet<KtSourceFile>>()
// TODO: the scripts checking should be part of the scripting plugin functionality, as it is implemented now in ScriptingProcessSourcesBeforeCompilingExtension
// TODO: implement in the next round of K2 scripting support (https://youtrack.jetbrains.com/issue/KT-55728)
val skipScriptsInLtMode = compilerConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR) && compilerConfiguration.getBoolean(CommonConfigurationKeys.USE_LIGHT_TREE)
var skipScriptsInLtModeWarning = false
compilerConfiguration.kotlinSourceRoots.forAllFiles(compilerConfiguration, projectEnvironment.project) { virtualFile, isCommon ->
compilerConfiguration.kotlinSourceRoots.forAllFiles(
compilerConfiguration,
projectEnvironment.project
) { virtualFile, isCommon, moduleName ->
val file = KtVirtualFileSourceFile(virtualFile)
when {
file.path.endsWith(javaFileExtensionWithDot) -> {}
file.path.endsWith(kotlinFileExtensionWithDot) || !skipScriptsInLtMode -> {
if (isCommon) commonSources.add(file)
else platformSources.add(file)
if (moduleName != null) {
sourcesByModuleName.getOrPut(moduleName) { mutableSetOf() }.add(file)
}
}
else -> {
// temporarily assume it is a script, see the TODO above
@@ -204,7 +219,7 @@ fun collectSources(
"Scripts are not yet supported with K2 in LightTree mode, consider using K1 or disable LightTree mode with -Xuse-fir-lt=false"
)
}
return Pair(platformSources, commonSources)
return GroupedKtSources(platformSources, commonSources, sourcesByModuleName)
}
fun convertAnalyzedFirToIr(
@@ -26,6 +26,7 @@ data class ModuleCompilerInput(
val commonSources: Collection<KtSourceFile>,
val platform: TargetPlatform,
val platformSources: Collection<KtSourceFile>,
val sourcesByModule: Map<String, Collection<KtSourceFile>>,
val configuration: CompilerConfiguration,
val friendFirModules: Collection<FirModuleData> = emptyList()
)
@@ -71,7 +71,7 @@ internal class FirMetadataSerializer(
projectEnvironment = environment.toAbstractProjectEnvironment() as VfsBasedProjectEnvironment
librariesScope = projectEnvironment.getSearchScopeForProjectLibraries()
librariesHelperScope = projectEnvironment.getSearchScopeForProjectLibraries()
ltFiles = collectSources(configuration, projectEnvironment, messageCollector).let { it.first + it.second }.toList()
ltFiles = collectSources(configuration, projectEnvironment, messageCollector).let { it.commonSources + it.platformSources }.toList()
sourceScope = projectEnvironment.getSearchScopeBySourceFiles(ltFiles)
providerAndScopeForIncrementalCompilation = createContextForIncrementalCompilation(
configuration,
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.codegen.CompilationException
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.config.getModuleNameForSource
import org.jetbrains.kotlin.metadata.builtins.BuiltInsBinaryVersion
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
@@ -64,8 +65,9 @@ class K2MetadataCompiler : CLICompiler<K2MetadataCompilerArguments>() {
if (pluginLoadResult != ExitCode.OK) return pluginLoadResult
val commonSources = arguments.commonSources?.toSet() ?: emptySet()
val hmppCliModuleStructure = configuration.get(CommonConfigurationKeys.HMPP_MODULE_STRUCTURE)
for (arg in arguments.freeArgs) {
configuration.addKotlinSourceRoot(arg, isCommon = arg in commonSources)
configuration.addKotlinSourceRoot(arg, isCommon = arg in commonSources, hmppCliModuleStructure?.getModuleNameForSource(arg))
}
if (arguments.classpath != null) {
configuration.addJvmClasspathRoots(arguments.classpath!!.split(File.pathSeparatorChar).map(::File))
@@ -19,3 +19,7 @@ class HmppCliModuleStructure(
val modules: List<HmppCliModule>,
val dependenciesMap: Map<HmppCliModule, List<HmppCliModule>>
)
fun HmppCliModuleStructure.getModuleNameForSource(source: String): String? {
return modules.firstOrNull { source in it.sources }?.name
}
@@ -91,10 +91,13 @@ abstract class AbstractFrontendModularizedTest : AbstractModularizedTest() {
configuration.addAll(
CLIConfigurationKeys.CONTENT_ROOTS,
moduleData.sources.filter { it.extension == "kt" || it.isDirectory }.map { KotlinSourceRoot(it.absolutePath, false) })
moduleData.sources
.filter { it.extension == "kt" || it.isDirectory }
.map { KotlinSourceRoot(it.absolutePath, isCommon = false, hmppModuleName = null) }
)
configuration.addAll(JVMConfigurationKeys.FRIEND_PATHS, moduleData.friendDirs.map { it.absolutePath })
return configuration
}
}
}
@@ -14,3 +14,4 @@ import org.jetbrains.kotlin.psi.UserDataProperty
* This setting only makes sense in the compiler, not in the IDE where sources from common modules are analyzed as common
*/
var KtFile.isCommonSource: Boolean? by UserDataProperty(Key.create("IS_COMMON_SOURCE"))
var KtFile.hmppModuleName: String? by UserDataProperty(Key.create("HMPP_MODULE_NAME"))
@@ -185,11 +185,15 @@ class IncrementalFirJvmCompilerRunner(
// -sources
val allPlatformSourceFiles = linkedSetOf<KtSourceFile>() // TODO: get from caller
val allCommonSourceFiles = linkedSetOf<KtSourceFile>()
val sourcesByModuleName = mutableMapOf<String, MutableSet<KtSourceFile>>()
configuration.kotlinSourceRoots.forAllFiles(configuration, projectEnvironment.project) { virtualFile, isCommon ->
configuration.kotlinSourceRoots.forAllFiles(configuration, projectEnvironment.project) { virtualFile, isCommon, hmppModule ->
val file = KtVirtualFileSourceFile(virtualFile)
if (isCommon) allCommonSourceFiles.add(file)
else allPlatformSourceFiles.add(file)
if (hmppModule != null) {
sourcesByModuleName.getOrPut(hmppModule) { mutableSetOf() }.add(file)
}
}
val diagnosticsReporter = DiagnosticReporterFactory.createPendingReporter()
@@ -207,11 +211,14 @@ class IncrementalFirJvmCompilerRunner(
fun firIncrementalCycle(): FirResult? {
while (true) {
val dirtySourcesByModuleName = sourcesByModuleName.mapValues { (_, sources) ->
sources.filter { dirtySources.any { df -> df.path == it.path } }
}
val compilerInput = ModuleCompilerInput(
targetId,
CommonPlatforms.defaultCommonPlatform, allCommonSourceFiles.filter { dirtySources.any { df -> df.path == it.path } },
JvmPlatforms.unspecifiedJvmPlatform, allPlatformSourceFiles.filter { dirtySources.any { df -> df.path == it.path } },
dirtySourcesByModuleName,
configuration
)
@@ -348,11 +355,13 @@ fun CompilerConfiguration.configureBaseRoots(args: K2JVMCompilerArguments) {
fun CompilerConfiguration.configureSourceRootsFromSources(
allSources: Collection<File>, commonSources: Set<File>, javaPackagePrefix: String?
) {
val hmppCliModuleStructure = get(CommonConfigurationKeys.HMPP_MODULE_STRUCTURE)
for (sourceFile in allSources) {
if (sourceFile.name.endsWith(JavaFileType.DOT_DEFAULT_EXTENSION)) {
addJavaSourceRoot(sourceFile, javaPackagePrefix)
} else {
addKotlinSourceRoot(sourceFile.path, isCommon = sourceFile in commonSources)
val path = sourceFile.path
addKotlinSourceRoot(path, isCommon = sourceFile in commonSources, hmppCliModuleStructure?.getModuleNameForSource(path))
if (sourceFile.isDirectory) {
addJavaSourceRoot(sourceFile, javaPackagePrefix)
@@ -9,14 +9,17 @@ import org.jetbrains.kotlin.cli.common.arguments.K2NativeCompilerArguments
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
import org.jetbrains.kotlin.cli.common.config.kotlinSourceRoots
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.getModuleNameForSource
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
fun CompilerConfiguration.setupFromArguments(arguments: K2NativeCompilerArguments) = with(KonanConfigKeys) {
val commonSources = arguments.commonSources?.toSet().orEmpty().map { it.absoluteNormalizedFile() }
val hmppModuleStructure = get(CommonConfigurationKeys.HMPP_MODULE_STRUCTURE)
arguments.freeArgs.forEach {
addKotlinSourceRoot(it, it.absoluteNormalizedFile() in commonSources)
addKotlinSourceRoot(it, isCommon = it.absoluteNormalizedFile() in commonSources, hmppModuleStructure?.getModuleNameForSource(it))
}
// Can be overwritten by explicit arguments below.
@@ -187,7 +187,7 @@ public class ExecuteKotlinScriptMojo extends AbstractMojo {
}
}
configuration.add(CLIConfigurationKeys.CONTENT_ROOTS, new KotlinSourceRoot(scriptFile.getAbsolutePath(), false));
configuration.add(CLIConfigurationKeys.CONTENT_ROOTS, new KotlinSourceRoot(scriptFile.getAbsolutePath(), false, null));
configuration.put(CommonConfigurationKeys.MODULE_NAME, JvmProtoBufUtil.DEFAULT_MODULE_NAME);
ConfigurationKt.configureScriptDefinitions(
@@ -339,6 +339,7 @@ private fun doCompileWithK2(
targetId,
CommonPlatforms.defaultCommonPlatform, emptyList(),
JvmPlatforms.unspecifiedJvmPlatform, sources,
sourcesByModule = emptyMap(),
kotlinCompilerConfiguration
)