Read script config if appropriate flag is specified, fix classpath handling

This commit is contained in:
Ilya Chernikov
2016-06-01 14:43:37 +02:00
parent abfda50077
commit 3e6616de42
10 changed files with 56 additions and 23 deletions
@@ -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");
}
@@ -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 })
}
@@ -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
View File
@@ -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
@@ -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()