show "kotlin not configured" editor notification
This commit is contained in:
+39
-5
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.configuration
|
|||||||
|
|
||||||
import com.intellij.ProjectTopics
|
import com.intellij.ProjectTopics
|
||||||
import com.intellij.openapi.fileEditor.FileEditor
|
import com.intellij.openapi.fileEditor.FileEditor
|
||||||
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.openapi.module.ModuleUtilCore
|
import com.intellij.openapi.module.ModuleUtilCore
|
||||||
import com.intellij.openapi.project.DumbAware
|
import com.intellij.openapi.project.DumbAware
|
||||||
import com.intellij.openapi.project.Project
|
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.ModuleRootManager
|
||||||
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
||||||
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService
|
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.util.Key
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.PsiFile
|
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.KotlinFileType
|
||||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
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(
|
class KotlinSetupSDKNotificationProvider(
|
||||||
private val myProject: Project,
|
private val myProject: Project,
|
||||||
notifications: EditorNotifications) : EditorNotifications.Provider<EditorNotificationPanel>(), DumbAware {
|
notifications: EditorNotifications) : EditorNotifications.Provider<EditorNotificationPanel>(), DumbAware {
|
||||||
@@ -63,17 +69,21 @@ class KotlinSetupSDKNotificationProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val module = ModuleUtilCore.findModuleForPsiElement(psiFile) ?: return null
|
val module = ModuleUtilCore.findModuleForPsiElement(psiFile) ?: return null
|
||||||
if (ModuleRootManager.getInstance(module).sdk != null) {
|
if (ModuleRootManager.getInstance(module).sdk == null) {
|
||||||
return null
|
return createSetupSdkPanel(myProject, psiFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
return createPanel(myProject, psiFile)
|
if (!isModuleConfigured(module) && UnsupportedAbiVersionNotificationPanelProvider.collectBadRoots(module).isEmpty()) {
|
||||||
|
return createKotlinNotConfiguredPanel(module)
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val KEY = Key.create<EditorNotificationPanel>("Setup SDK")
|
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 {
|
return EditorNotificationPanel().apply {
|
||||||
setText(ProjectBundle.message("project.sdk.not.defined"))
|
setText(ProjectBundle.message("project.sdk.not.defined"))
|
||||||
createActionLabel(ProjectBundle.message("project.sdk.setup")) {
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-5
@@ -107,20 +107,18 @@ class UnsupportedAbiVersionNotificationPanelProvider(private val project: Projec
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createShowPathsActionLabel(module: Module, answer: EditorNotificationPanel, labelText: String) {
|
private fun createShowPathsActionLabel(module: Module, answer: EditorNotificationPanel, labelText: String) {
|
||||||
val label: Ref<HyperlinkLabel> = Ref.create()
|
answer.createComponentActionLabel(labelText) { label ->
|
||||||
val action = Runnable {
|
|
||||||
DumbService.getInstance(project).tryRunReadActionInSmartMode({
|
DumbService.getInstance(project).tryRunReadActionInSmartMode({
|
||||||
val badRoots = collectBadRoots(module)
|
val badRoots = collectBadRoots(module)
|
||||||
assert(!badRoots.isEmpty()) { "This action should only be called when bad roots are present" }
|
assert(!badRoots.isEmpty()) { "This action should only be called when bad roots are present" }
|
||||||
|
|
||||||
val listPopupModel = LibraryRootsPopupModel("Unsupported format", project, badRoots)
|
val listPopupModel = LibraryRootsPopupModel("Unsupported format", project, badRoots)
|
||||||
val popup = JBPopupFactory.getInstance().createListPopup(listPopupModel)
|
val popup = JBPopupFactory.getInstance().createListPopup(listPopupModel)
|
||||||
popup.showUnderneathOf(label.get())
|
popup.showUnderneathOf(label)
|
||||||
|
|
||||||
null
|
null
|
||||||
}, "Can't show all paths during index update")
|
}, "Can't show all paths during index update")
|
||||||
}
|
}
|
||||||
label.set(answer.createActionLabel(labelText, action))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getKey(): Key<EditorNotificationPanel> = KEY
|
override fun getKey(): Key<EditorNotificationPanel> = KEY
|
||||||
@@ -207,7 +205,7 @@ class UnsupportedAbiVersionNotificationPanelProvider(private val project: Projec
|
|||||||
OpenFileDescriptor(project, root).navigate(true)
|
OpenFileDescriptor(project, root).navigate(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun collectBadRoots(module: Module): Collection<VirtualFile> {
|
fun collectBadRoots(module: Module): Collection<VirtualFile> {
|
||||||
val badJVMRoots = getLibraryRootsWithAbiIncompatibleKotlinClasses(module)
|
val badJVMRoots = getLibraryRootsWithAbiIncompatibleKotlinClasses(module)
|
||||||
val badJSRoots = getLibraryRootsWithAbiIncompatibleForKotlinJs(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))
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user