Introduce -Xcommon-sources and pass it correctly from build tool plugins

#KT-25196 In Progress
This commit is contained in:
Alexander Udalov
2018-07-27 14:15:12 +02:00
parent d35e73d29b
commit 0f003802fe
28 changed files with 205 additions and 126 deletions
@@ -10,14 +10,18 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
interface ContentRoot
data class KotlinSourceRoot(val path: String): 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
fun CompilerConfiguration.addKotlinSourceRoot(source: String) {
add(CLIConfigurationKeys.CONTENT_ROOTS, KotlinSourceRoot(source))
@JvmOverloads
fun CompilerConfiguration.addKotlinSourceRoot(path: String, isCommon: Boolean = false) {
add(CLIConfigurationKeys.CONTENT_ROOTS, KotlinSourceRoot(path, isCommon))
}
fun CompilerConfiguration.addKotlinSourceRoots(sources: List<String>): Unit =
sources.forEach(this::addKotlinSourceRoot)
sources.forEach { addKotlinSourceRoot(it) }
val CompilerConfiguration.kotlinSourceRoots: List<String>
get() = get(CLIConfigurationKeys.CONTENT_ROOTS)?.filterIsInstance<KotlinSourceRoot>()?.map { it.path }.orEmpty()
val CompilerConfiguration.kotlinSourceRoots: List<KotlinSourceRoot>
get() = get(CLIConfigurationKeys.CONTENT_ROOTS)?.filterIsInstance<KotlinSourceRoot>().orEmpty()
@@ -26,6 +26,7 @@ import com.intellij.util.ExceptionUtil;
import com.intellij.util.SmartList;
import kotlin.collections.ArraysKt;
import kotlin.collections.CollectionsKt;
import kotlin.collections.SetsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.analyzer.AnalysisResult;
@@ -175,7 +176,12 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
configuration.put(JSConfigurationKeys.LIBRARIES, configureLibraries(arguments, paths, messageCollector));
ContentRootsKt.addKotlinSourceRoots(configuration, arguments.getFreeArgs());
String[] commonSourcesArray = arguments.getCommonSources();
Set<String> commonSources = commonSourcesArray == null ? Collections.emptySet() : SetsKt.setOf(commonSourcesArray);
for (String arg : arguments.getFreeArgs()) {
ContentRootsKt.addKotlinSourceRoot(configuration, arg, commonSources.contains(arg));
}
KotlinCoreEnvironment environmentForJS =
KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JS_CONFIG_FILES);
@@ -77,13 +77,14 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
val pluginLoadResult = loadPlugins(arguments, configuration)
if (pluginLoadResult != ExitCode.OK) return pluginLoadResult
val commonSources = arguments.commonSources?.toSet().orEmpty()
if (!arguments.script && arguments.buildFile == null) {
for (arg in arguments.freeArgs) {
val file = File(arg)
if (file.extension == JavaFileType.DEFAULT_EXTENSION) {
configuration.addJavaSourceRoot(file)
} else {
configuration.addKotlinSourceRoot(arg)
configuration.addKotlinSourceRoot(arg, isCommon = arg in commonSources)
if (file.isDirectory) {
configuration.addJavaSourceRoot(file)
}
@@ -69,6 +69,7 @@ import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.CliModuleVisibilityManagerImpl
import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY
import org.jetbrains.kotlin.cli.common.config.ContentRoot
import org.jetbrains.kotlin.cli.common.config.KotlinSourceRoot
import org.jetbrains.kotlin.cli.common.config.kotlinSourceRoots
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
@@ -110,6 +111,7 @@ import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtens
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
import org.jetbrains.kotlin.resolve.lazy.declarations.CliDeclarationProviderFactoryService
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
import org.jetbrains.kotlin.script.ScriptDefinitionProvider
import org.jetbrains.kotlin.script.ScriptDependenciesProvider
import org.jetbrains.kotlin.script.ScriptReportSink
@@ -400,16 +402,18 @@ class KotlinCoreEnvironment private constructor(
private fun findJarRoot(file: File): VirtualFile? =
applicationEnvironment.jarFileSystem.findFileByPath("$file${URLUtil.JAR_SEPARATOR}")
private fun getSourceRootsCheckingForDuplicates(): Collection<String> {
val uniqueSourceRoots = linkedSetOf<String>()
private fun getSourceRootsCheckingForDuplicates(): List<KotlinSourceRoot> {
val uniqueSourceRoots = hashSetOf<String>()
val result = mutableListOf<KotlinSourceRoot>()
configuration.kotlinSourceRoots.forEach { path ->
if (!uniqueSourceRoots.add(path)) {
report(STRONG_WARNING, "Duplicate source root: $path")
for (root in configuration.kotlinSourceRoots) {
if (!uniqueSourceRoots.add(root.path)) {
report(STRONG_WARNING, "Duplicate source root: ${root.path}")
}
result.add(root)
}
return uniqueSourceRoots
return result
}
fun getSourceFiles(): List<KtFile> = sourceFiles
@@ -425,7 +429,7 @@ class KotlinCoreEnvironment private constructor(
val virtualFileCreator = PreprocessedFileCreator(project)
for (sourceRootPath in sourceRoots) {
for ((sourceRootPath, isCommon) in sourceRoots) {
val vFile = localFileSystem.findFileByPath(sourceRootPath)
if (vFile == null) {
val message = "Source file or directory not found: $sourceRootPath"
@@ -452,6 +456,9 @@ class KotlinCoreEnvironment private constructor(
val psiFile = psiManager.findFile(virtualFile)
if (psiFile is KtFile) {
result.add(psiFile)
if (isCommon) {
psiFile.isCommonSource = true
}
}
}
}
@@ -34,7 +34,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoots
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.OUTPUT
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.WARNING
@@ -65,18 +65,6 @@ import java.lang.reflect.InvocationTargetException
import java.net.URLClassLoader
object KotlinToJVMBytecodeCompiler {
private fun getAbsoluteFiles(buildFile: File, module: Module): List<File> {
return module.getSourceFiles().map { sourceFile ->
val source = File(sourceFile)
if (!source.isAbsolute) {
File(buildFile.absoluteFile.parentFile, sourceFile)
} else {
source
}
}
}
private fun writeOutput(
configuration: CompilerConfiguration,
outputFiles: OutputFileCollection,
@@ -142,7 +130,7 @@ object KotlinToJVMBytecodeCompiler {
for (module in chunk) {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
val moduleSourceFiles = getAbsoluteFiles(buildFile, module).map { file -> localFileSystem.findFileByPath(file.path) }
val moduleSourceFiles = getAbsolutePaths(buildFile, module.getSourceFiles()).map(localFileSystem::findFileByPath)
val ktFiles = environment.getSourceFiles().filter { file -> file.virtualFile in moduleSourceFiles }
if (!checkKotlinPackageUsage(environment, ktFiles)) return false
@@ -184,7 +172,11 @@ object KotlinToJVMBytecodeCompiler {
internal fun configureSourceRoots(configuration: CompilerConfiguration, chunk: List<Module>, buildFile: File) {
for (module in chunk) {
configuration.addKotlinSourceRoots(getAbsoluteFiles(buildFile, module).map(File::getPath))
val commonSources = getAbsolutePaths(buildFile, module.getCommonSourceFiles()).toSet()
for (path in getAbsolutePaths(buildFile, module.getSourceFiles())) {
configuration.addKotlinSourceRoot(path, isCommon = path in commonSources)
}
}
for (module in chunk) {
@@ -224,6 +216,16 @@ object KotlinToJVMBytecodeCompiler {
configuration.addAll(JVMConfigurationKeys.MODULES, chunk)
}
private fun getAbsolutePaths(buildFile: File, sourceFilePaths: List<String>): List<String> =
sourceFilePaths.map { path ->
val sourceFile = File(path)
if (!sourceFile.isAbsolute) {
File(buildFile.absoluteFile.parentFile, path).absolutePath
} else {
sourceFile.absolutePath
}
}
private fun findMainClass(generationState: GenerationState, files: List<KtFile>): FqName? {
val mainFunctionDetector = MainFunctionDetector(generationState.bindingContext)
return files.asSequence()
@@ -60,7 +60,7 @@ class K2MetadataCompiler : CLICompiler<K2MetadataCompilerArguments>() {
if (pluginLoadResult != ExitCode.OK) return pluginLoadResult
for (arg in arguments.freeArgs) {
configuration.addKotlinSourceRoot(arg)
configuration.addKotlinSourceRoot(arg, isCommon = true)
}
if (arguments.classpath != null) {
configuration.addJvmClasspathRoots(arguments.classpath!!.split(File.pathSeparatorChar).map(::File))