Implement simple "add to compilation" functionality for scripts
(incomplete import - scripts added to the compilation but not yet imported into scope) Base functionality needed for #KT-27960
This commit is contained in:
@@ -22,7 +22,6 @@ import com.intellij.codeInsight.InferredAnnotationsManager
|
||||
import com.intellij.codeInsight.runner.JavaMainMethodProvider
|
||||
import com.intellij.core.*
|
||||
import com.intellij.ide.highlighter.JavaFileType
|
||||
import com.intellij.ide.plugins.PluginManagerCore
|
||||
import com.intellij.lang.MetaLanguage
|
||||
import com.intellij.lang.java.JavaParserDefinition
|
||||
import com.intellij.openapi.Disposable
|
||||
@@ -241,16 +240,11 @@ class KotlinCoreEnvironment private constructor(
|
||||
}
|
||||
|
||||
sourceFiles += createKtFiles(project)
|
||||
sourceFiles.sortBy { it.virtualFile.path }
|
||||
|
||||
if (scriptDefinitionProvider != null) {
|
||||
ScriptDependenciesProvider.getInstance(project).let { importsProvider ->
|
||||
configuration.addJvmClasspathRoots(
|
||||
sourceFiles.mapNotNull(importsProvider::getScriptDependencies)
|
||||
.flatMap { it.classpath }
|
||||
.distinctBy { it.absolutePath })
|
||||
}
|
||||
sourceFiles += collectRequiredSourcesFromDependencies(configuration, project, sourceFiles)
|
||||
}
|
||||
sourceFiles.sortBy { it.virtualFile.path }
|
||||
|
||||
val jdkHome = configuration.get(JVMConfigurationKeys.JDK_HOME)
|
||||
val jrtFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL)
|
||||
@@ -427,61 +421,13 @@ class KotlinCoreEnvironment private constructor(
|
||||
|
||||
fun getSourceFiles(): List<KtFile> = sourceFiles
|
||||
|
||||
private fun createKtFiles(project: Project): List<KtFile> {
|
||||
val sourceRoots = getSourceRootsCheckingForDuplicates()
|
||||
private fun createKtFiles(project: Project): List<KtFile> =
|
||||
createSourceFilesFromSourceRoots(configuration, project, 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, isCommon) 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)
|
||||
if (isCommon) {
|
||||
psiFile.isCommonSource = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun report(severity: CompilerMessageSeverity, message: String) {
|
||||
configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(severity, message)
|
||||
}
|
||||
internal fun report(severity: CompilerMessageSeverity, message: String) = report(configuration, severity, message)
|
||||
|
||||
companion object {
|
||||
private val LOG = Logger.getInstance(KotlinCoreEnvironment::class.java)
|
||||
internal val LOG = Logger.getInstance(KotlinCoreEnvironment::class.java)
|
||||
|
||||
private val APPLICATION_LOCK = Object()
|
||||
private var ourApplicationEnvironment: JavaCoreApplicationEnvironment? = null
|
||||
@@ -701,3 +647,85 @@ class KotlinCoreEnvironment private constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun report(configuration: CompilerConfiguration, severity: CompilerMessageSeverity, message: String) {
|
||||
configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(severity, message)
|
||||
}
|
||||
|
||||
private fun createSourceFilesFromSourceRoots(
|
||||
configuration: CompilerConfiguration,
|
||||
project: Project,
|
||||
sourceRoots: List<KotlinSourceRoot>
|
||||
): MutableList<KtFile> {
|
||||
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, isCommon) 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()) {
|
||||
KotlinCoreEnvironment.LOG.warn("$message\n\nbuild file path: $buildFilePath\ncontent:\n${buildFilePath.readText()}")
|
||||
}
|
||||
|
||||
report(configuration, ERROR, message)
|
||||
continue
|
||||
}
|
||||
|
||||
if (!vFile.isDirectory && vFile.fileType != KotlinFileType.INSTANCE) {
|
||||
report(configuration, 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)
|
||||
if (isCommon) {
|
||||
psiFile.isCommonSource = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun collectRequiredSourcesFromDependencies(
|
||||
configuration: CompilerConfiguration,
|
||||
project: Project,
|
||||
initialSources: Iterable<KtFile>
|
||||
): List<KtFile> {
|
||||
val collectedSources = ArrayList<KtFile>()
|
||||
val importsProvider = ScriptDependenciesProvider.getInstance(project)
|
||||
var remainingSources = initialSources.sortedBy { it.virtualFile.path }
|
||||
val knownSourcePaths = HashSet<String>()
|
||||
while (true) {
|
||||
val dependencies = remainingSources.mapNotNull(importsProvider::getScriptDependencies)
|
||||
configuration.addJvmClasspathRoots(dependencies.flatMap { it.classpath }.distinctBy { it.absolutePath })
|
||||
val addedSourceRoots = dependencies.flatMap { it.scripts.map { KotlinSourceRoot(it.path, false) } }
|
||||
val addedSources = createSourceFilesFromSourceRoots(configuration, project, addedSourceRoots)
|
||||
val newSources = if (addedSources.isEmpty()) emptyList() else {
|
||||
remainingSources.forEach { knownSourcePaths.add(it.virtualFile.path) }
|
||||
addedSources.filterNot { knownSourcePaths.contains(it.virtualFile.path) }
|
||||
}
|
||||
if (newSources.isEmpty()) break
|
||||
else {
|
||||
collectedSources += newSources
|
||||
remainingSources = newSources
|
||||
}
|
||||
}
|
||||
return collectedSources
|
||||
}
|
||||
|
||||
+1
-1
@@ -267,7 +267,7 @@ object KotlinToJVMBytecodeCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
internal fun compileAndExecuteScript(environment: KotlinCoreEnvironment, scriptArgs: List<String>): ExitCode {
|
||||
fun compileAndExecuteScript(environment: KotlinCoreEnvironment, scriptArgs: List<String>): ExitCode {
|
||||
val scriptClass = compileScript(environment) ?: return ExitCode.COMPILATION_ERROR
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user