K/N: Clean-up logic for import of K/N projects from Gradle

This commit is contained in:
Dmitriy Dolovov
2018-09-07 12:29:36 +03:00
committed by Mikhail Glukhikh
parent dd203830a8
commit 88638ef655
10 changed files with 1 additions and 343 deletions
@@ -1,14 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.konan.gradle
import com.intellij.openapi.project.Project
import org.jetbrains.konan.settings.KonanModelProvider
import java.nio.file.Path
class GradleKonanModelProvider : KonanModelProvider {
override fun getKonanHome(project: Project): Path? = null
}
@@ -1,17 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.konan.gradle
import com.intellij.openapi.project.Project
import org.jetbrains.konan.settings.KonanProjectComponent
import org.jetbrains.plugins.gradle.settings.GradleSettings
class GradleKonanProjectComponent(project: Project) : KonanProjectComponent(project) {
override fun looksLikeKotlinNativeProject(): Boolean {
//TODO not just any gradle project
return GradleSettings.getInstance(project).linkedProjectsSettings.isNotEmpty()
}
}
@@ -1,96 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.konan
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.Task
import com.intellij.openapi.project.Project
import com.intellij.util.SystemProperties.getUserHome
import com.intellij.util.io.exists
import com.intellij.util.net.IOExceptionDialog
import org.jetbrains.konan.settings.KonanProjectComponent
import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.util.DependencyDownloaderHTTPResponseException
import org.jetbrains.kotlin.konan.util.DependencyProcessor
import org.jetbrains.kotlin.konan.util.DependencySource
import java.nio.file.Path
import java.nio.file.Paths
class KotlinNativeToolchain(
val version: String,
val repoUrl: String
) {
private val artifactName = "kotlin-native-$KONAN_OS-$version"
val baseDir: Path get() = Paths.get("${getUserHome()}/.konan/$artifactName")
val konanc: Path get() = baseDir.resolve("bin/konanc")
val cinterop: Path get() = baseDir.resolve("bin/cinterop")
fun ensureExists(project: Project) {
ApplicationManager.getApplication().assertIsDispatchThread()
if (baseDir.exists()) return
for (attempt in 0..3) {
var exception: Throwable? = null
object : Task.Modal(project, "Downloading Kotlin/Native $version", false) {
override fun run(progress: ProgressIndicator) {
DependencyProcessor(
baseDir.parent.toFile(),
repoUrl,
mapOf(artifactName to listOf(DependencySource.Remote.Public)),
customProgressCallback = { _, downloaded, total ->
progress.fraction = downloaded / maxOf(total, downloaded, 1).toDouble()
}
).run()
ApplicationManager.getApplication().invokeLater {
project.getComponent(KonanProjectComponent::class.java).reloadLibraries()
}
}
override fun onThrowable(error: Throwable) {
exception = error
}
}.queue()
val ex = exception
val tryAgain = if (ex == null) {
false
} else {
val details = if (ex is DependencyDownloaderHTTPResponseException) {
"Server returned ${ex.responseCode} when trying to download ${ex.url}."
} else {
LOG.error(ex)
"Unknown error occurred."
}
IOExceptionDialog.showErrorDialog(
"Failed to download Kotlin/Native",
details
)
}
if (!tryAgain) break
}
}
companion object {
fun looksLikeBundledToolchain(path: String): Boolean =
Paths.get(path).startsWith(Paths.get("${getUserHome()}/.konan/"))
private val KONAN_OS = HostManager.simpleOsName()
//todo: fixme
private val BUNDLED_VERSION = "0.8" //bundledFile("kotlin-native-version").readText().trim()
private val BUILD_DIR = "releases"
val BUNDLED = KotlinNativeToolchain(
version = BUNDLED_VERSION,
repoUrl = "https://download.jetbrains.com/kotlin/native/builds/$BUILD_DIR/$BUNDLED_VERSION/$KONAN_OS"
)
private val LOG = Logger.getInstance(KotlinNativeToolchain::class.java)
}
}
@@ -1,24 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.konan
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.startup.StartupActivity
import org.jetbrains.konan.settings.KonanProjectComponent
class SetupKotlinNativeStartupActivity : StartupActivity {
override fun runActivity(project: Project) {
//todo: looks like without default project component (like disabled Gradle plugin) we will get exception here (that's bad)
if (!KonanProjectComponent.getInstance(project).looksLikeKotlinNativeProject()) return
ensureKotlinNativeExists(project)
}
private fun ensureKotlinNativeExists(project: Project) {
ApplicationManager.getApplication().assertIsDispatchThread()
KotlinNativeToolchain.BUNDLED.ensureExists(project)
}
}
@@ -1,25 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.konan.settings
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.target.CompilerOutputKind.*
import org.jetbrains.kotlin.konan.target.KonanTarget
import java.nio.file.Path
data class KonanArtifact(
val targetName: String,
val moduleName: String,
val type: CompilerOutputKind,
val target: KonanTarget?,
val libraryDependencies: List<String>,
val sources: List<Path>,
val output: Path
)
val CompilerOutputKind.isLibrary: Boolean get() = this == LIBRARY || this == DYNAMIC || this == STATIC || this == FRAMEWORK
val CompilerOutputKind.isExecutable: Boolean get() = this == PROGRAM
val CompilerOutputKind.isTest: Boolean get() = false //TODO
@@ -1,25 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.konan.settings;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
import com.intellij.util.messages.Topic;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.nio.file.Path;
@ApiStatus.Experimental
public interface KonanModelProvider {
Topic<Runnable> RELOAD_TOPIC = new Topic<>("Kotlin/Native Project Model Updater", Runnable.class);
ExtensionPointName<KonanModelProvider> EP_NAME = ExtensionPointName.create("org.jetbrains.kotlin.native.konanModelProvider");
@Nullable
Path getKonanHome(@NotNull Project project);
}
@@ -1,55 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.konan.settings
import com.intellij.openapi.components.ProjectComponent
import com.intellij.openapi.project.Project
import com.intellij.util.io.exists
import com.intellij.util.io.isDirectory
import org.jetbrains.konan.KotlinNativeToolchain
import org.jetbrains.kotlin.konan.library.*
import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget
import java.nio.file.Files
import java.nio.file.Path
import java.util.stream.Collectors
open class KonanPaths(protected val project: Project) : ProjectComponent {
companion object {
fun getInstance(project: Project): KonanPaths = project.getComponent(KonanPaths::class.java)
fun bundledKonanDist(): Path = KotlinNativeToolchain.BUNDLED.baseDir
}
override fun getComponentName() = "Kotlin/Native Compiler Paths"
fun konanStdlib(): Path? = konanDist()?.resolve(konanCommonLibraryPath(KONAN_STDLIB_NAME))
open fun konanDist(): Path? {
for (provider in KonanModelProvider.EP_NAME.extensions) {
provider.getKonanHome(project)?.existing()?.let { return it }
}
return bundledKonanDist()
}
open fun libraryPaths(): Set<Path> = emptySet()
fun konanPlatformLibraries(): List<Path> {
val resolvedTargetName = HostManager.resolveAlias(target().name)
val klibPath =
konanDist()?.resolve(konanSpecificPlatformLibrariesPath(resolvedTargetName))?.existing() ?: return emptyList()
return Files.walk(klibPath, 1).filter {
it.isDirectory() && it.fileName.toString() != KONAN_STDLIB_NAME && it != klibPath
}.collect(Collectors.toList())
}
//todo: this is wrong, we are not allowing multiple targets in project
open fun target(): KonanTarget = HostManager.host
}
private fun Path.existing(): Path? = takeIf { exists() }
@@ -1,64 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.konan.settings
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.components.ProjectComponent
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.libraries.LibraryTable
import com.intellij.openapi.vfs.*
import org.jetbrains.konan.KotlinNativeToolchain
import org.jetbrains.konan.settings.KonanModelProvider.RELOAD_TOPIC
import org.jetbrains.kotlin.utils.addIfNotNull
import java.nio.file.Path
abstract class KonanProjectComponent(val project: Project) : ProjectComponent {
companion object {
fun getInstance(project: Project): KonanProjectComponent = project.getComponent(KonanProjectComponent::class.java)
}
protected var libraryPaths: Set<String> = emptySet()
override fun getComponentName(): String = "Kotlin/Native Project Component"
override fun projectOpened() {
VirtualFileManager.getInstance().addVirtualFileListener(object : VirtualFileListener {
override fun fileCreated(event: VirtualFileEvent) {
val filePath = event.file.path
if (libraryPaths.contains(filePath)) reloadLibraries()
}
}, project)
val connection = project.messageBus.connect(project)
connection.subscribe(RELOAD_TOPIC, Runnable {
ApplicationManager.getApplication().invokeLater {
KotlinNativeToolchain.BUNDLED.ensureExists(project)
reloadLibraries()
}
})
if (looksLikeKotlinNativeProject()) {
reloadLibraries()
}
}
open fun reloadLibraries(): Unit = synchronized(this) {
}
protected open fun collectLibraryPaths(): MutableSet<Path> {
val konanPaths = KonanPaths.getInstance(project)
return mutableSetOf<Path>().apply {
addIfNotNull(konanPaths.konanStdlib())
addAll(konanPaths.konanPlatformLibraries())
}
}
abstract fun looksLikeKotlinNativeProject(): Boolean
}
+1 -11
View File
@@ -17,15 +17,5 @@
<implementation-class>org.jetbrains.konan.gradle.internal.KotlinNativeIdeInitializer</implementation-class>
</component>
</application-components>
<project-components>
<component>
<interface-class>org.jetbrains.konan.settings.KonanProjectComponent</interface-class>
<implementation-class>org.jetbrains.konan.gradle.GradleKonanProjectComponent</implementation-class>
</component>
</project-components>
<extensions defaultExtensionNs="org.jetbrains.kotlin.native">
<konanModelProvider implementation="org.jetbrains.konan.gradle.GradleKonanModelProvider"/>
</extensions>
<!-- /NATIVE PART -->
</idea-plugin>
-12
View File
@@ -8,18 +8,7 @@
</component>
</application-components>
<project-components>
<component>
<implementation-class>org.jetbrains.konan.settings.KonanPaths</implementation-class>
</component>
</project-components>
<extensionPoints>
<extensionPoint qualifiedName="org.jetbrains.kotlin.native.konanModelProvider" interface="org.jetbrains.konan.settings.KonanModelProvider"/>
</extensionPoints>
<extensions defaultExtensionNs="com.intellij">
<postStartupActivity implementation="org.jetbrains.konan.SetupKotlinNativeStartupActivity"/>
<psi.classFileDecompiler implementation="org.jetbrains.konan.analyser.index.KonanMetadataDecompiler"/>
<fileType.fileViewProviderFactory filetype="KNM"
@@ -32,7 +21,6 @@
<extensions defaultExtensionNs="org.jetbrains.kotlin">
<binaryExtension implementation="org.jetbrains.konan.analyser.index.KonanMetaBinary"/>
<!--<idePlatformSupport implementation="org.jetbrains.konan.analyser.KonanPlatformSupport" order="first"/>-->
<idePlatformKind implementation="org.jetbrains.kotlin.ide.konan.NativeIdePlatformKind"/>
<idePlatformKindTooling implementation="org.jetbrains.kotlin.ide.konan.NativeIdePlatformKindTooling"/>
<idePlatformKindResolution implementation="org.jetbrains.kotlin.ide.konan.NativePlatformKindResolution"/>