Introduce and use KotlinPaths.getStdlibPath()

Also support renaming .jar file when updating an existing library
This commit is contained in:
Dmitry Jemerov
2017-03-31 12:47:19 +02:00
parent 344f372327
commit f9495aa0d7
17 changed files with 82 additions and 62 deletions
@@ -49,7 +49,7 @@ open class KotlinJvmReplService(
protected val configuration = CompilerConfiguration().apply {
addJvmClasspathRoots(PathUtil.getJdkClassesRoots())
addJvmClasspathRoots(PathUtil.getKotlinPathsForCompiler().let { listOf(it.runtimePath, it.reflectPath, it.scriptRuntimePath) })
addJvmClasspathRoots(PathUtil.getKotlinPathsForCompiler().let { listOf(it.stdlibPath, it.reflectPath, it.scriptRuntimePath) })
addJvmClasspathRoots(templateClasspath)
put(CommonConfigurationKeys.MODULE_NAME, "kotlin-script")
languageVersionSettings = LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE).apply {
@@ -27,9 +27,15 @@ public interface KotlinPaths {
@NotNull
File getLibPath();
/**
* @deprecated Use getStdlibPath() instead
*/
@NotNull
File getRuntimePath();
@NotNull
File getStdlibPath();
@NotNull
File getReflectPath();
@@ -46,6 +46,12 @@ public class KotlinPathsFromHomeDir implements KotlinPaths {
return getLibraryFile(PathUtil.KOTLIN_JAVA_RUNTIME_JAR);
}
@NotNull
@Override
public File getStdlibPath() {
return getLibraryFile(PathUtil.KOTLIN_JAVA_STDLIB_JAR);
}
@NotNull
@Override
public File getReflectPath() {
@@ -69,7 +69,7 @@ class KotlinConsoleKeeper(val project: Project) {
//paramList.add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005")
val kotlinPaths = PathUtil.getKotlinPathsForIdeaPlugin()
val replClassPath = listOf(kotlinPaths.compilerPath, kotlinPaths.reflectPath, kotlinPaths.runtimePath, kotlinPaths.scriptRuntimePath)
val replClassPath = listOf(kotlinPaths.compilerPath, kotlinPaths.reflectPath, kotlinPaths.stdlibPath, kotlinPaths.scriptRuntimePath)
.map { it.absolutePath }
.joinToString(File.pathSeparator)
@@ -66,7 +66,7 @@ public class ConfigLibraryUtil {
}
public static void configureKotlinRuntime(Module module) {
addLibrary(getKotlinRuntimeLibEditor(DEFAULT_JAVA_RUNTIME_LIB_NAME, PathUtil.getKotlinPathsForDistDirectory().getRuntimePath()),
addLibrary(getKotlinRuntimeLibEditor(DEFAULT_JAVA_RUNTIME_LIB_NAME, PathUtil.getKotlinPathsForDistDirectory().getStdlibPath()),
module);
addLibrary(getKotlinRuntimeLibEditor(DEFAULT_KOTLIN_TEST_LIB_NAME, PathUtil.getKotlinPathsForDistDirectory().getKotlinTestPath()),
module);
@@ -66,7 +66,7 @@ public class JdkAndMockLibraryProjectDescriptor extends KotlinLightProjectDescri
Library.ModifiableModel libraryModel = model.getModuleLibraryTable().getModifiableModel().createLibrary(LIBRARY_NAME).getModifiableModel();
libraryModel.addRoot(jarUrl, OrderRootType.CLASSES);
if (withRuntime) {
libraryModel.addRoot(getJarUrl(PathUtil.getKotlinPathsForDistDirectory().getRuntimePath()), OrderRootType.CLASSES);
libraryModel.addRoot(getJarUrl(PathUtil.getKotlinPathsForDistDirectory().getStdlibPath()), OrderRootType.CLASSES);
}
if (withSources) {
libraryModel.addRoot(jarUrl + "src/", OrderRootType.SOURCES);
@@ -59,7 +59,7 @@ open class KotlinJavaModuleConfigurator internal constructor() : KotlinWithLibra
get() {
val paths = PathUtil.getKotlinPathsForIdeaPlugin()
return RuntimeLibraryFiles(
assertFileExists(paths.runtimePath),
assertFileExists(paths.stdlibPath),
assertFileExists(paths.reflectPath),
assertFileExists(paths.runtimeSourcesPath)
)
@@ -107,14 +107,6 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj
collector.showNotification()
}
fun configureSilently(project: Project) {
val defaultPathToJar = getDefaultPathToJarFile(project)
val collector = createConfigureKotlinNotificationCollector(project)
for (module in ModuleManager.getInstance(project).modules) {
configureModuleWithLibrary(module, defaultPathToJar, null, collector)
}
}
protected fun configureModuleWithLibrary(
module: Module,
defaultPath: String,
@@ -68,7 +68,7 @@ class KotlinBundledScriptDependencies(override val javaHome: String?) : KotlinSc
return with(PathUtil.getKotlinPathsForIdeaPlugin()) {
listOf(
reflectPath,
runtimePath,
stdlibPath,
scriptRuntimePath
)
}
@@ -25,18 +25,19 @@ import com.intellij.openapi.projectRoots.JavaSdkVersion
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.LibraryOrderEntry
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.ProjectFileIndex
import com.intellij.openapi.roots.libraries.Library
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.JarFileSystem
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiClass
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.util.PathUtil.getLocalFile
import com.intellij.util.PathUtil.getLocalPath
import com.intellij.util.containers.MultiMap
import com.intellij.util.indexing.FileBasedIndex
import com.intellij.util.indexing.ScalarIndexExtension
@@ -56,7 +57,6 @@ import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
import org.jetbrains.kotlin.utils.JsMetadataVersion
import org.jetbrains.kotlin.utils.PathUtil
import java.io.File
import java.io.IOException
fun getLibraryRootsWithAbiIncompatibleKotlinClasses(module: Module): Collection<BinaryVersionedFile<JvmMetadataVersion>> {
return getLibraryRootsWithAbiIncompatibleVersion(module, JvmMetadataVersion.INSTANCE, KotlinJvmMetadataVersionIndex)
@@ -91,25 +91,25 @@ fun updateLibraries(project: Project, libraries: Collection<Library>) {
for (library in libraries) {
if (isDetected(JavaRuntimePresentationProvider.getInstance(), library)) {
updateJar(project, getRuntimeJar(library), LibraryJarDescriptor.RUNTIME_JAR)
updateJar(project, getReflectJar(library), LibraryJarDescriptor.REFLECT_JAR)
updateJar(project, getTestJar(library), LibraryJarDescriptor.TEST_JAR)
updateJar(project, library, getRuntimeJar(library), LibraryJarDescriptor.RUNTIME_JAR)
updateJar(project, library, getReflectJar(library), LibraryJarDescriptor.REFLECT_JAR)
updateJar(project, library,getTestJar(library), LibraryJarDescriptor.TEST_JAR)
if (kJvmConfigurator.changeOldSourcesPathIfNeeded(library, collector)) {
kJvmConfigurator.copySourcesToPathFromLibrary(library, collector)
}
else {
updateJar(project, getRuntimeSrcJar(library), LibraryJarDescriptor.RUNTIME_SRC_JAR)
updateJar(project, library, getRuntimeSrcJar(library), LibraryJarDescriptor.RUNTIME_SRC_JAR)
}
}
else if (isDetected(JSLibraryStdPresentationProvider.getInstance(), library)) {
updateJar(project, getJsStdLibJar(library), LibraryJarDescriptor.JS_STDLIB_JAR)
updateJar(project, library, getJsStdLibJar(library), LibraryJarDescriptor.JS_STDLIB_JAR)
if (kJsConfigurator.changeOldSourcesPathIfNeeded(library, collector)) {
kJsConfigurator.copySourcesToPathFromLibrary(library, collector)
}
else {
updateJar(project, getJsStdLibSrcJar(library), LibraryJarDescriptor.JS_STDLIB_SRC_JAR)
updateJar(project, library, getJsStdLibSrcJar(library), LibraryJarDescriptor.JS_STDLIB_SRC_JAR)
}
}
}
@@ -119,15 +119,17 @@ fun updateLibraries(project: Project, libraries: Collection<Library>) {
private fun updateJar(
project: Project,
library: Library,
fileToReplace: VirtualFile?,
libraryJarDescriptor: LibraryJarDescriptor) {
if (fileToReplace == null && !libraryJarDescriptor.shouldExist) {
return
}
val oldUrl = fileToReplace?.url
val paths = PathUtil.getKotlinPathsForIdeaPlugin()
val jarPath: File = when (libraryJarDescriptor) {
LibraryJarDescriptor.RUNTIME_JAR -> paths.runtimePath
LibraryJarDescriptor.RUNTIME_JAR -> paths.stdlibPath
LibraryJarDescriptor.REFLECT_JAR -> paths.reflectPath
LibraryJarDescriptor.SCRIPT_RUNTIME_JAR -> paths.scriptRuntimePath
LibraryJarDescriptor.TEST_JAR -> paths.kotlinTestPath
@@ -141,7 +143,21 @@ private fun updateJar(
return
}
replaceFile(jarPath, getLocalJar(fileToReplace)!!)
val jarFileToReplace = getLocalJar(fileToReplace)!!
val newVFile = replaceFile(jarPath, jarFileToReplace)
if (newVFile != null) {
val model = library.modifiableModel
try {
if (oldUrl != null) {
model.removeRoot(oldUrl, OrderRootType.CLASSES)
}
val newRoot = JarFileSystem.getInstance().getJarRootForLocalFile(newVFile)!!
model.addRoot(newRoot, OrderRootType.CLASSES)
}
finally {
model.commit()
}
}
}
fun findAllUsedLibraries(project: Project): MultiMap<Library, Module> {
@@ -163,7 +179,7 @@ fun findAllUsedLibraries(project: Project): MultiMap<Library, Module> {
}
private enum class LibraryJarDescriptor(val jarName: String, val shouldExist: Boolean) {
RUNTIME_JAR(PathUtil.KOTLIN_JAVA_RUNTIME_JAR, true),
RUNTIME_JAR(PathUtil.KOTLIN_JAVA_STDLIB_JAR, true),
REFLECT_JAR(PathUtil.KOTLIN_JAVA_REFLECT_JAR, false),
SCRIPT_RUNTIME_JAR(PathUtil.KOTLIN_JAVA_SCRIPT_RUNTIME_JAR, true),
TEST_JAR(PathUtil.KOTLIN_TEST_JAR, false),
@@ -217,25 +233,25 @@ fun getLocalJar(kotlinRuntimeJar: VirtualFile?): VirtualFile? {
return kotlinRuntimeJar
}
internal fun replaceFile(updatedFile: File, replacedJarFile: VirtualFile) {
try {
val replacedFile = getLocalFile(replacedJarFile)
internal fun replaceFile(updatedFile: File, jarFileToReplace: VirtualFile): VirtualFile? {
val jarIoFileToReplace = File(jarFileToReplace.path)
val localPath = getLocalPath(replacedFile) ?:
error("Should be called for replacing valid root file: $replacedJarFile")
if (FileUtil.filesEqual(updatedFile, jarIoFileToReplace)) {
return null
}
val libraryJarPath = File(localPath)
if (FileUtil.filesEqual(updatedFile, libraryJarPath)) {
return
FileUtil.copy(updatedFile, jarIoFileToReplace)
if (jarIoFileToReplace.name != updatedFile.name) {
val newFile = File(jarIoFileToReplace.parent, updatedFile.name)
if (!newFile.exists()) {
jarIoFileToReplace.renameTo(newFile)
return LocalFileSystem.getInstance().findFileByIoFile(newFile)!!.apply {
refresh(false, true)
}
}
FileUtil.copy(updatedFile, libraryJarPath)
replacedFile.refresh(false, true)
}
catch (e: IOException) {
throw AssertionError(e)
}
jarFileToReplace.refresh(false, true)
return null
}
data class BinaryVersionedFile<out T : BinaryVersion>(val file: VirtualFile, val version: T, val supportedVersion: T)
@@ -48,7 +48,7 @@ class KotlinUpdatePluginComponent : ApplicationComponent {
val ideaPluginPaths = PathUtil.getKotlinPathsForIdeaPlugin()
// Force refresh jar handlers
requestFullJarUpdate(ideaPluginPaths.runtimePath)
requestFullJarUpdate(ideaPluginPaths.stdlibPath)
requestFullJarUpdate(ideaPluginPaths.reflectPath)
requestFullJarUpdate(ideaPluginPaths.scriptRuntimePath)
requestFullJarUpdate(ideaPluginPaths.runtimeSourcesPath)
@@ -106,7 +106,7 @@ public abstract class AbstractConfigureKotlinTest extends PlatformTestCase {
}
private static String getPathToExistentRuntimeJar() {
return PathUtil.getKotlinPathsForDistDirectory().getRuntimePath().getParent();
return PathUtil.getKotlinPathsForDistDirectory().getStdlibPath().getParent();
}
private static String getPathToExistentJsJar() {
@@ -24,13 +24,12 @@ import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEdito
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.JarFileSystem
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder
import org.jetbrains.kotlin.idea.facet.KotlinFacetType
import org.jetbrains.kotlin.idea.framework.JavaRuntimeDetectionUtil
import org.jetbrains.kotlin.idea.facet.getRuntimeLibraryVersion
import org.jetbrains.kotlin.idea.project.getLanguageVersionSettings
import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
@@ -73,14 +72,14 @@ class LanguageFeatureQuickFixTest : LightPlatformCodeInsightFixtureTestCase() {
}
fun testEnableCoroutines_UpdateRuntime() {
val runtime = configureRuntime("mockRuntime106")
configureRuntime("mockRuntime106")
resetProjectSettings(LanguageVersion.KOTLIN_1_1)
myFixture.configureByText("foo.kt", "suspend fun foo()")
assertEquals(LanguageFeature.State.ENABLED_WITH_WARNING, coroutineSupport)
myFixture.launchAction(myFixture.findSingleIntention("Enable coroutine support in the project"))
assertEquals(LanguageFeature.State.ENABLED, coroutineSupport)
assertEquals(bundledRuntimeVersion(), JavaRuntimeDetectionUtil.getJavaRuntimeVersion(listOf(runtime)))
assertEquals(bundledRuntimeVersion(), getRuntimeLibraryVersion(myFixture.module))
}
fun testIncreaseLangLevel() {
@@ -120,7 +119,7 @@ class LanguageFeatureQuickFixTest : LightPlatformCodeInsightFixtureTestCase() {
}
fun testIncreaseLangAndApiLevel_10() {
val runtime = configureRuntime("mockRuntime106")
configureRuntime("mockRuntime106")
resetProjectSettings(LanguageVersion.KOTLIN_1_0)
myFixture.configureByText("foo.kt", "val x = <caret>\"s\"::length")
@@ -129,11 +128,11 @@ class LanguageFeatureQuickFixTest : LightPlatformCodeInsightFixtureTestCase() {
assertEquals("1.1", KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.languageVersion)
assertEquals("1.1", KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.apiVersion)
assertEquals(bundledRuntimeVersion(), JavaRuntimeDetectionUtil.getJavaRuntimeVersion(listOf(runtime)))
assertEquals(bundledRuntimeVersion(), getRuntimeLibraryVersion(myFixture.module))
}
fun testIncreaseLangLevelFacet_10() {
val runtime = configureRuntime("mockRuntime106")
configureRuntime("mockRuntime106")
resetProjectSettings(LanguageVersion.KOTLIN_1_0)
configureKotlinFacet(myModule) {
settings.languageLevel = LanguageVersion.KOTLIN_1_0
@@ -145,12 +144,13 @@ class LanguageFeatureQuickFixTest : LightPlatformCodeInsightFixtureTestCase() {
myFixture.launchAction(myFixture.findSingleIntention("Set module language version to 1.1"))
assertEquals(LanguageVersion.KOTLIN_1_1, myModule.languageVersionSettings.languageVersion)
assertEquals(bundledRuntimeVersion(), JavaRuntimeDetectionUtil.getJavaRuntimeVersion(listOf(runtime)))
assertEquals(bundledRuntimeVersion(), getRuntimeLibraryVersion(myFixture.module))
}
private fun configureRuntime(path: String): VirtualFile {
val tempFile = FileUtil.createTempFile("kotlin-runtime", ".jar")
FileUtil.copy(File("idea/testData/configuration/$path/kotlin-runtime.jar"), tempFile)
private fun configureRuntime(path: String) {
val name = if (path == "mockRuntime106") "kotlin-runtime" else "kotlin-stdlib"
val tempFile = FileUtil.createTempFile(name, ".jar")
FileUtil.copy(File("idea/testData/configuration/$path/$name.jar"), tempFile)
val tempVFile = LocalFileSystem.getInstance().findFileByIoFile(tempFile)!!
updateModel(myFixture.module) { model ->
@@ -161,8 +161,7 @@ class LanguageFeatureQuickFixTest : LightPlatformCodeInsightFixtureTestCase() {
ConfigLibraryUtil.addLibrary(editor, model)
}
return tempVFile
}
}
private fun resetProjectSettings(version: LanguageVersion) {
KotlinCommonCompilerArgumentsHolder.getInstance(project).update {
@@ -19,9 +19,9 @@ package org.jetbrains.kotlin.kapt3.test
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.util.text.StringUtil
import com.sun.tools.javac.tree.JCTree
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.codegen.CodegenTestCase
import org.jetbrains.kotlin.codegen.CodegenTestUtil
import org.jetbrains.kotlin.codegen.state.GenerationState
@@ -160,7 +160,7 @@ abstract class AbstractKotlinKapt3IntegrationTest : CodegenTestCase() {
options: Map<String, String>,
stubsOutputDir: File,
incrementalDataOutputDir: File
) : AbstractKapt3Extension(PathUtil.getJdkClassesRoots() + PathUtil.getKotlinPathsForIdeaPlugin().runtimePath,
) : AbstractKapt3Extension(PathUtil.getJdkClassesRoots() + PathUtil.getKotlinPathsForIdeaPlugin().stdlibPath,
emptyList(), javaSourceRoots, outputDir, outputDir,
stubsOutputDir, incrementalDataOutputDir, options, "", true, System.currentTimeMillis(),
KaptLogger(true), correctErrorTypes = true
@@ -25,7 +25,9 @@ import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
import org.jetbrains.kotlin.codegen.CodegenTestCase
import org.jetbrains.kotlin.codegen.CodegenTestUtil
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.kapt3.*
import org.jetbrains.kotlin.kapt3.Kapt3BuilderFactory
import org.jetbrains.kotlin.kapt3.KaptContext
import org.jetbrains.kotlin.kapt3.doAnnotationProcessing
import org.jetbrains.kotlin.kapt3.stubs.ClassFileToSourceStubConverter
import org.jetbrains.kotlin.kapt3.util.KaptLogger
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
@@ -34,9 +36,9 @@ import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.util.trimTrailingWhitespacesAndAddNewlineAtEOF
import org.jetbrains.kotlin.utils.PathUtil
import com.sun.tools.javac.util.List as JavacList
import java.io.File
import java.nio.file.Files
import com.sun.tools.javac.util.List as JavacList
abstract class AbstractKotlinKapt3Test : CodegenTestCase() {
companion object {
@@ -116,7 +118,7 @@ abstract class AbstractKotlinKaptContextTest : AbstractKotlinKapt3Test() {
val sourceOutputDir = Files.createTempDirectory("kaptRunner").toFile()
try {
kaptRunner.doAnnotationProcessing(emptyList(), listOf(JavaKaptContextTest.simpleProcessor()),
compileClasspath = PathUtil.getJdkClassesRoots() + PathUtil.getKotlinPathsForIdeaPlugin().runtimePath,
compileClasspath = PathUtil.getJdkClassesRoots() + PathUtil.getKotlinPathsForIdeaPlugin().stdlibPath,
annotationProcessingClasspath = emptyList(), annotationProcessors = "",
sourcesOutputDir = sourceOutputDir, classesOutputDir = sourceOutputDir,
additionalSources = compilationUnits, withJdk = true)
@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.test.TestJdkKind
import org.jetbrains.kotlin.utils.KotlinPaths
import org.jetbrains.kotlin.utils.PathUtil
import org.jetbrains.kotlin.utils.tryConstructClassFromStringArgs
import org.junit.Ignore
import java.io.*
import java.lang.management.ManagementFactory
import java.net.URLClassLoader
@@ -60,7 +59,7 @@ class SourceSectionsTest : TestCaseWithTmpdir() {
}
val compilerClassPath = listOf(kotlinPaths.compilerPath)
val scriptRuntimeClassPath = listOf( kotlinPaths.runtimePath, kotlinPaths.scriptRuntimePath)
val scriptRuntimeClassPath = listOf( kotlinPaths.stdlibPath, kotlinPaths.scriptRuntimePath)
val sourceSectionsPluginJar = File(kotlinPaths.libPath, "source-sections-compiler-plugin.jar")
val compilerId by lazy(LazyThreadSafetyMode.NONE) { CompilerId.makeCompilerId(compilerClassPath) }