Read script config if appropriate flag is specified, fix classpath handling
This commit is contained in:
+3
@@ -77,6 +77,9 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments {
|
||||
@ValueDescription("<path>")
|
||||
public String declarationsOutputPath;
|
||||
|
||||
@Argument(value = "Xload-script-configs", description = "Load script configuration files from project directory tree")
|
||||
public boolean loadScriptConfigs;
|
||||
|
||||
// Paths to output directories for friend modules.
|
||||
public String[] friendPaths;
|
||||
|
||||
|
||||
@@ -284,6 +284,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
configuration.put(JVMConfigurationKeys.INHERIT_MULTIFILE_PARTS, arguments.inheritMultifileParts)
|
||||
configuration.put(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE, arguments.allowKotlinPackage)
|
||||
configuration.put(CLIConfigurationKeys.REPORT_PERF, arguments.reportPerf)
|
||||
configuration.put(JVMConfigurationKeys.LOAD_SCRIPT_CONFIGS, arguments.loadScriptConfigs)
|
||||
|
||||
arguments.declarationsOutputPath?.let { configuration.put(JVMConfigurationKeys.DECLARATIONS_JSON_PATH, it) }
|
||||
}
|
||||
|
||||
@@ -138,12 +138,21 @@ class KotlinCoreEnvironment private constructor(
|
||||
KotlinScriptDefinitionProvider.getInstance(project).let { scriptDefinitionProvider ->
|
||||
scriptDefinitionProvider.scriptDefinitions =
|
||||
configuration.getList(JVMConfigurationKeys.SCRIPT_DEFINITIONS)
|
||||
.ifEmpty { listOf(StandardScriptDefinition) }
|
||||
.ifEmpty {
|
||||
if (configuration.get(JVMConfigurationKeys.LOAD_SCRIPT_CONFIGS) ?: false)
|
||||
loadScriptConfigsFromProjectRoot(File(project.basePath ?: ".")).let { configs ->
|
||||
val kotlinEnvVars = generateKotlinScriptClasspathEnvVars(project)
|
||||
configs.map { KotlinConfigurableScriptDefinition(it, kotlinEnvVars) } + StandardScriptDefinition
|
||||
}
|
||||
else null
|
||||
?: listOf(StandardScriptDefinition)
|
||||
}
|
||||
|
||||
configuration.addJvmClasspathRoots(
|
||||
sourceFiles
|
||||
.mapNotNull { src -> src.virtualFile?.let { scriptDefinitionProvider.findScriptDefinition(it) } }
|
||||
.flatMap { it.getScriptDependenciesClasspath().map { File(it).canonicalFile } }
|
||||
.mapNotNull { src -> src.virtualFile }
|
||||
.flatMap { getScriptCombinedClasspath(it, project) }
|
||||
.map { File(it).canonicalFile }
|
||||
.distinct())
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,9 @@ public class JVMConfigurationKeys {
|
||||
public static final CompilerConfigurationKey<List<Module>> MODULES =
|
||||
CompilerConfigurationKey.create("module data");
|
||||
|
||||
public static final CompilerConfigurationKey<Boolean> LOAD_SCRIPT_CONFIGS =
|
||||
CompilerConfigurationKey.create("Load script configuration files from project directory tree");
|
||||
|
||||
public static final CompilerConfigurationKey<List<String>> FRIEND_PATHS =
|
||||
CompilerConfigurationKey.create("friend module paths");
|
||||
}
|
||||
|
||||
+25
-12
@@ -30,7 +30,10 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
||||
import org.jetbrains.kotlin.psi.KtScript
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.KotlinPaths
|
||||
import org.jetbrains.kotlin.utils.KotlinPathsFromHomeDir
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import java.io.File
|
||||
|
||||
|
||||
class KotlinConfigurableScriptDefinition(val config: KotlinScriptConfig, val environmentVars: Map<String, List<String>>?) : KotlinScriptDefinition {
|
||||
@@ -73,16 +76,26 @@ internal fun List<String>.evalWithVars(varsMap: Map<String, List<String>>?): Lis
|
||||
}
|
||||
}
|
||||
|
||||
fun generateKotlinScriptClasspathEnvVarsForCompiler(project: Project): Map<String, List<String>> {
|
||||
val paths = PathUtil.getKotlinPathsForCompiler()
|
||||
return mapOf("kotlin-runtime" to listOf(paths.runtimePath.canonicalPath),
|
||||
"project-root" to listOf(project.basePath ?: "."),
|
||||
"jdk" to PathUtil.getJdkClassesRoots().map { it.canonicalPath })
|
||||
}
|
||||
fun generateKotlinScriptClasspathEnvVars(project: Project, kotlinHomeDir: File? = null): Map<String, List<String>> =
|
||||
generateKotlinScriptClasspathEnvVarsFromPaths(
|
||||
project,
|
||||
kotlinHomeDir?.let { KotlinPathsFromHomeDir(it) } ?: tryFindKotlinPathsForScriptClasspathEnvVars(project))
|
||||
|
||||
private fun tryFindKotlinPathsForScriptClasspathEnvVars(project: Project): KotlinPaths? =
|
||||
sequenceOf( { PathUtil.getKotlinPathsForIdeaPlugin() },
|
||||
{ PathUtil.getKotlinPathsForJpsPlugin() },
|
||||
{ PathUtil.getKotlinPathsForCompiler() },
|
||||
{ KotlinPathsFromHomeDir(File(project.basePath ?: ".")) },
|
||||
// note: these are only usable when debugging kotlin project
|
||||
// TODO: replace with more reliable mechanism
|
||||
{ KotlinPathsFromHomeDir(File(PathUtil.getPathUtilJar().parentFile.parentFile.parentFile, "dist/kotlinc")) })
|
||||
.map { it() }
|
||||
.firstOrNull { it.runtimePath.exists() }
|
||||
|
||||
private fun generateKotlinScriptClasspathEnvVarsFromPaths(project: Project, paths: KotlinPaths?): Map<String, List<String>> =
|
||||
mapOf("kotlin-runtime" to (paths?.run { listOf(runtimePath.canonicalPath) } ?: emptyList()),
|
||||
"kotlin-reflect" to (paths?.run { listOf(reflectPath.canonicalPath) } ?: emptyList()),
|
||||
"project-root" to listOf(project.basePath ?: "."),
|
||||
"jdk" to PathUtil.getJdkClassesRoots().map { it.canonicalPath })
|
||||
.filterNot { it.value.isEmpty() }
|
||||
|
||||
fun generateKotlinScriptClasspathEnvVarsForIdea(project: Project): Map<String, List<String>> {
|
||||
val paths = PathUtil.getKotlinPathsForIdeaPlugin()
|
||||
return mapOf("kotlin-runtime" to listOf(paths.runtimePath.canonicalPath),
|
||||
"project-root" to listOf(project.basePath ?: "."),
|
||||
"jdk" to PathUtil.getJdkClassesRoots().map { it.canonicalPath })
|
||||
}
|
||||
|
||||
+2
-2
@@ -26,12 +26,12 @@ import kotlin.concurrent.write
|
||||
class KotlinScriptExtraImportsProvider(val project: Project) {
|
||||
private val lock = ReentrantReadWriteLock()
|
||||
private val cache = hashMapOf<VirtualFile, List<KotlinScriptExtraImport>>()
|
||||
private val envVars: Map<String, List<String>> by lazy { generateKotlinScriptClasspathEnvVarsForIdea(project) }
|
||||
private val envVars: Map<String, List<String>> by lazy { generateKotlinScriptClasspathEnvVars(project) }
|
||||
|
||||
fun isExtraImportsConfig(file: VirtualFile): Boolean = file.name.endsWith(IMPORTSFILEEXTENSION)
|
||||
|
||||
fun getExtraImports(file: VirtualFile): List<KotlinScriptExtraImport> = lock.read {
|
||||
if (file.isInLocalFileSystem)
|
||||
if (file.isValid)
|
||||
cache.getOrPut(file) {
|
||||
file.parent.findFileByRelativePath(file.name + IMPORTSFILEEXTENSION)?.let {
|
||||
loadScriptExtraImportConfigs(it.inputStream).map { KotlinScriptExtraImportFromConfig(it, envVars) }
|
||||
|
||||
@@ -35,9 +35,13 @@ fun getScriptExtraImports(psiFile: PsiFile): List<KotlinScriptExtraImport> =
|
||||
} ?: emptyList()
|
||||
|
||||
fun getScriptCombinedClasspath(file: VirtualFile, project: Project): List<String> =
|
||||
(getScriptDefinition(file, project)?.getScriptDependenciesClasspath() ?: emptyList()) +
|
||||
getScriptExtraImports(file, project).flatMap { it.classpath }
|
||||
getScriptDefinition(file, project)?.run {
|
||||
getScriptDependenciesClasspath() +
|
||||
getScriptExtraImports(file, project).flatMap { it.classpath }
|
||||
} ?: emptyList()
|
||||
|
||||
fun getScriptCombinedClasspath(psiFile: PsiFile): List<String> =
|
||||
(getScriptDefinition(psiFile) ?.getScriptDependenciesClasspath() ?: emptyList()) +
|
||||
getScriptExtraImports(psiFile).flatMap { it.classpath }
|
||||
getScriptDefinition(psiFile)?.run {
|
||||
getScriptDependenciesClasspath() +
|
||||
getScriptExtraImports(psiFile).flatMap { it.classpath }
|
||||
} ?: emptyList()
|
||||
|
||||
+1
@@ -8,6 +8,7 @@ where advanced options include:
|
||||
-Xallow-kotlin-package Allow compiling code in package 'kotlin'
|
||||
-Xskip-metadata-version-check Try loading binary incompatible classes, may cause crashes
|
||||
-Xdump-declarations-to <path> Path to JSON file to dump Java to Kotlin declaration mappings
|
||||
-Xload-script-configs Load script configuration files from project directory tree
|
||||
-Xno-inline Disable method inlining
|
||||
-Xrepeat <count> Repeat compilation (for performance analysis)
|
||||
-Xplugin <path> Load plugins from the given classpath
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.asJava.KtLightElement
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionProvider
|
||||
import org.jetbrains.kotlin.script.getScriptDefinition
|
||||
import org.jetbrains.kotlin.script.getScriptExtraImports
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ class KotlinScriptConfigurationManager(private val project: Project,
|
||||
private val kotlinScriptDependenciesIndexableSetContributor: KotlinScriptDependenciesIndexableSetContributor?
|
||||
) : AbstractProjectComponent(project) {
|
||||
|
||||
private val kotlinEnvVars: Map<String, List<String>> by lazy { generateKotlinScriptClasspathEnvVarsForIdea(myProject) }
|
||||
private val kotlinEnvVars: Map<String, List<String>> by lazy { generateKotlinScriptClasspathEnvVars(myProject) }
|
||||
|
||||
init {
|
||||
reloadScriptDefinitions()
|
||||
|
||||
Reference in New Issue
Block a user