Refactor CompileEnvironmentUtil.getKtFiles, move to KotlinCoreEnvironment

Do not call this method the second time in KotlinToJVMBytecodeCompiler
where all KtFile instances are already created; just get only those
files that are in the needed module, which can be determined solely by
the file path.

Also "kotlinize" getKtFiles and rename to createKtFiles
This commit is contained in:
Alexander Udalov
2018-07-27 14:49:47 +02:00
parent fe829add44
commit 1582354077
3 changed files with 54 additions and 90 deletions
@@ -16,21 +16,9 @@
package org.jetbrains.kotlin.cli.jvm.compiler;
import com.google.common.collect.Lists;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.vfs.StandardFileSystems;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.VirtualFileSystem;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import kotlin.Unit;
import kotlin.io.FilesKt;
import kotlin.jvm.functions.Function1;
import kotlin.sequences.SequencesKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.output.OutputFile;
@@ -38,27 +26,16 @@ import org.jetbrains.kotlin.backend.common.output.OutputFileCollection;
import org.jetbrains.kotlin.cli.common.messages.MessageCollector;
import org.jetbrains.kotlin.cli.common.modules.ModuleChunk;
import org.jetbrains.kotlin.cli.common.modules.ModuleXmlParser;
import org.jetbrains.kotlin.config.CompilerConfiguration;
import org.jetbrains.kotlin.config.JVMConfigurationKeys;
import org.jetbrains.kotlin.extensions.PreprocessedFileCreator;
import org.jetbrains.kotlin.idea.KotlinFileType;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
import org.jetbrains.kotlin.utils.PathUtil;
import java.io.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.jar.*;
import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR;
public class CompileEnvironmentUtil {
private static final Logger LOG = Logger.getInstance(CompileEnvironmentUtil.class);
@NotNull
public static ModuleChunk loadModuleChunk(File buildFile, MessageCollector messageCollector) {
if (!buildFile.exists()) {
@@ -139,61 +116,4 @@ public class CompileEnvironmentUtil {
}
}
}
@NotNull
public static List<KtFile> getKtFiles(
@NotNull Project project,
@NotNull Collection<String> sourceRoots,
@NotNull CompilerConfiguration configuration,
@NotNull Function1<String, Unit> reportError
) throws IOException {
VirtualFileSystem localFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL);
Set<VirtualFile> processedFiles = new HashSet<>();
List<KtFile> result = Lists.newArrayList();
PreprocessedFileCreator virtualFileCreator = new PreprocessedFileCreator(project);
for (String sourceRootPath : sourceRoots) {
if (sourceRootPath == null) {
continue;
}
VirtualFile vFile = localFileSystem.findFileByPath(sourceRootPath);
if (vFile == null) {
String message = "Source file or directory not found: " + sourceRootPath;
File buildFilePath = configuration.get(JVMConfigurationKeys.MODULE_XML_FILE);
if (buildFilePath != null && Logger.isInitialized()) {
LOG.warn(message +
"\n\nbuild file path: " + buildFilePath +
"\ncontent:\n" + FileUtil.loadFile(buildFilePath));
}
reportError.invoke(message);
continue;
}
if (!vFile.isDirectory() && vFile.getFileType() != KotlinFileType.INSTANCE) {
reportError.invoke("Source entry is not a Kotlin file: " + sourceRootPath);
continue;
}
SequencesKt.forEach(FilesKt.walkTopDown(new File(sourceRootPath)), file -> {
if (file.isFile()) {
VirtualFile originalVirtualFile = localFileSystem.findFileByPath(file.getAbsolutePath());
VirtualFile virtualFile = originalVirtualFile != null ? virtualFileCreator.create(originalVirtualFile) : null;
if (virtualFile != null && !processedFiles.contains(virtualFile)) {
processedFiles.add(virtualFile);
PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
if (psiFile instanceof KtFile) {
result.add((KtFile) psiFile);
}
}
}
return Unit.INSTANCE;
});
}
return result;
}
}
@@ -32,6 +32,7 @@ import com.intellij.openapi.Disposable
import com.intellij.openapi.application.TransactionGuard
import com.intellij.openapi.application.TransactionGuardImpl
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.extensions.ExtensionsArea
import com.intellij.openapi.fileTypes.FileTypeExtensionPoint
@@ -90,10 +91,7 @@ import org.jetbrains.kotlin.config.APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.extensions.CompilerConfigurationExtension
import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension
import org.jetbrains.kotlin.extensions.PreprocessedVirtualFileFactoryExtension
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
import org.jetbrains.kotlin.extensions.*
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.js.translate.extensions.JsSyntheticTranslateExtension
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache
@@ -218,9 +216,7 @@ class KotlinCoreEnvironment private constructor(
extension.updateConfiguration(configuration)
}
sourceFiles += CompileEnvironmentUtil.getKtFiles(project, getSourceRootsCheckingForDuplicates(), this.configuration) { message ->
report(ERROR, message)
}
sourceFiles += createKtFiles(project)
sourceFiles.sortBy { it.virtualFile.path }
// If not disabled explicitly, we should always support at least the standard script definition
@@ -416,6 +412,52 @@ class KotlinCoreEnvironment private constructor(
fun getSourceFiles(): List<KtFile> = sourceFiles
private fun createKtFiles(project: Project): List<KtFile> {
val sourceRoots = getSourceRootsCheckingForDuplicates()
val localFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL)
val psiManager = PsiManager.getInstance(project)
val processedFiles = hashSetOf<VirtualFile>()
val result = mutableListOf<KtFile>()
val virtualFileCreator = PreprocessedFileCreator(project)
for (sourceRootPath in sourceRoots) {
val vFile = localFileSystem.findFileByPath(sourceRootPath)
if (vFile == null) {
val message = "Source file or directory not found: $sourceRootPath"
val buildFilePath = configuration.get(JVMConfigurationKeys.MODULE_XML_FILE)
if (buildFilePath != null && Logger.isInitialized()) {
LOG.warn("$message\n\nbuild file path: $buildFilePath\ncontent:\n${buildFilePath.readText()}")
}
report(ERROR, message)
continue
}
if (!vFile.isDirectory && vFile.fileType != KotlinFileType.INSTANCE) {
report(ERROR, "Source entry is not a Kotlin file: $sourceRootPath")
continue
}
for (file in File(sourceRootPath).walkTopDown()) {
if (!file.isFile) continue
val virtualFile = localFileSystem.findFileByPath(file.absolutePath)?.let(virtualFileCreator::create)
if (virtualFile != null && processedFiles.add(virtualFile)) {
val psiFile = psiManager.findFile(virtualFile)
if (psiFile is KtFile) {
result.add(psiFile)
}
}
}
}
return result
}
private fun report(severity: CompilerMessageSeverity, message: String) {
configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(severity, message)
}
@@ -425,6 +467,8 @@ class KotlinCoreEnvironment private constructor(
setCompatibleBuild()
}
private val LOG = Logger.getInstance(KotlinCoreEnvironment::class.java)
private val APPLICATION_LOCK = Object()
private var ourApplicationEnvironment: JavaCoreApplicationEnvironment? = null
private var ourProjectCount = 0
@@ -138,9 +138,9 @@ object KotlinToJVMBytecodeCompiler {
for (module in chunk) {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
val ktFiles = CompileEnvironmentUtil.getKtFiles(
environment.project, getAbsolutePaths(buildFile, module), projectConfiguration
) { path -> throw IllegalStateException("Should have been checked before: $path") }
val moduleSourcePaths = getAbsolutePaths(buildFile, module)
val ktFiles = environment.getSourceFiles().filter { file -> file.virtualFilePath in moduleSourcePaths }
if (!checkKotlinPackageUsage(environment, ktFiles)) return false
val moduleConfiguration = projectConfiguration.copy().apply {