show "kotlin not configured" editor notification

This commit is contained in:
Dmitry Jemerov
2016-01-19 17:20:09 +01:00
parent 170ba98b20
commit 4910b06f2c
2 changed files with 50 additions and 10 deletions
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.configuration
import com.intellij.ProjectTopics
import com.intellij.openapi.fileEditor.FileEditor
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleUtilCore
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.Project
@@ -27,6 +28,9 @@ import com.intellij.openapi.roots.ModuleRootEvent
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ModuleRootModificationUtil
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService
import com.intellij.openapi.ui.popup.JBPopupFactory
import com.intellij.openapi.ui.popup.PopupStep
import com.intellij.openapi.ui.popup.util.BaseListPopupStep
import com.intellij.openapi.util.Key
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiFile
@@ -36,8 +40,10 @@ import com.intellij.ui.EditorNotifications
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.idea.versions.UnsupportedAbiVersionNotificationPanelProvider
import org.jetbrains.kotlin.idea.versions.createComponentActionLabel
// Code is very same to com.intellij.codeInsight.daemon.impl.SetupSDKNotificationProvider
// Code is partially copied from com.intellij.codeInsight.daemon.impl.SetupSDKNotificationProvider
class KotlinSetupSDKNotificationProvider(
private val myProject: Project,
notifications: EditorNotifications) : EditorNotifications.Provider<EditorNotificationPanel>(), DumbAware {
@@ -63,17 +69,21 @@ class KotlinSetupSDKNotificationProvider(
}
val module = ModuleUtilCore.findModuleForPsiElement(psiFile) ?: return null
if (ModuleRootManager.getInstance(module).sdk != null) {
return null
if (ModuleRootManager.getInstance(module).sdk == null) {
return createSetupSdkPanel(myProject, psiFile)
}
return createPanel(myProject, psiFile)
if (!isModuleConfigured(module) && UnsupportedAbiVersionNotificationPanelProvider.collectBadRoots(module).isEmpty()) {
return createKotlinNotConfiguredPanel(module)
}
return null
}
companion object {
private val KEY = Key.create<EditorNotificationPanel>("Setup SDK")
private fun createPanel(project: Project, file: PsiFile): EditorNotificationPanel {
private fun createSetupSdkPanel(project: Project, file: PsiFile): EditorNotificationPanel {
return EditorNotificationPanel().apply {
setText(ProjectBundle.message("project.sdk.not.defined"))
createActionLabel(ProjectBundle.message("project.sdk.setup")) {
@@ -88,5 +98,29 @@ class KotlinSetupSDKNotificationProvider(
}
}
}
private fun createKotlinNotConfiguredPanel(module: Module): EditorNotificationPanel {
return EditorNotificationPanel().apply {
setText("Kotlin not configured")
val configurators = getApplicableConfigurators(module).toList()
if (!configurators.isEmpty()) {
createComponentActionLabel("Configure") { label ->
val step = object : BaseListPopupStep<KotlinProjectConfigurator>("Choose Configurator", configurators) {
override fun getTextFor(value: KotlinProjectConfigurator?): String {
return value?.presentableText ?: "<none>"
}
override fun onChosen(selectedValue: KotlinProjectConfigurator?, finalChoice: Boolean): PopupStep<*>? {
selectedValue?.let {
it.configure(module.project, emptyList())
}
return null
}
}
JBPopupFactory.getInstance().createListPopup(step).showUnderneathOf(label)
}
}
}
}
}
}
@@ -107,20 +107,18 @@ class UnsupportedAbiVersionNotificationPanelProvider(private val project: Projec
}
private fun createShowPathsActionLabel(module: Module, answer: EditorNotificationPanel, labelText: String) {
val label: Ref<HyperlinkLabel> = Ref.create()
val action = Runnable {
answer.createComponentActionLabel(labelText) { label ->
DumbService.getInstance(project).tryRunReadActionInSmartMode({
val badRoots = collectBadRoots(module)
assert(!badRoots.isEmpty()) { "This action should only be called when bad roots are present" }
val listPopupModel = LibraryRootsPopupModel("Unsupported format", project, badRoots)
val popup = JBPopupFactory.getInstance().createListPopup(listPopupModel)
popup.showUnderneathOf(label.get())
popup.showUnderneathOf(label)
null
}, "Can't show all paths during index update")
}
label.set(answer.createActionLabel(labelText, action))
}
override fun getKey(): Key<EditorNotificationPanel> = KEY
@@ -207,7 +205,7 @@ class UnsupportedAbiVersionNotificationPanelProvider(private val project: Projec
OpenFileDescriptor(project, root).navigate(true)
}
private fun collectBadRoots(module: Module): Collection<VirtualFile> {
fun collectBadRoots(module: Module): Collection<VirtualFile> {
val badJVMRoots = getLibraryRootsWithAbiIncompatibleKotlinClasses(module)
val badJSRoots = getLibraryRootsWithAbiIncompatibleForKotlinJs(module)
@@ -217,3 +215,11 @@ class UnsupportedAbiVersionNotificationPanelProvider(private val project: Projec
}
}
}
fun EditorNotificationPanel.createComponentActionLabel(labelText: String, callback: (HyperlinkLabel) -> Unit) {
val label: Ref<HyperlinkLabel> = Ref.create()
val action = Runnable {
callback(label.get())
}
label.set(createActionLabel(labelText, action))
}