‘com.intellij.codeInsight.codeVisionProvider’Why is this extension point not supported in 2022.2?
Answered
‘com.intellij.codeInsight.codeVisionProvider’Why is this extension point not supported in 2022.2?
报错如下图所示:
Please sign in to leave a comment.
Please provide more details.
I have a version compatibility issue regarding 'Inlay Hints'
It can be displayed normally in 'IntelliJ IDEA2022.3.3'. as the picture shows:
Exhibiting exception in 'IntelliJ IDEA2022.2.3'. as the picture shows:
Error message:
java.lang.AbstractMethodError: Receiver class com.github.liminany.leanissjetbrainsideextension.inlay.CodeVisionInlay does not define or inherit an implementation of the resolved method 'abstract java.lang.String getGroupId()' of interface com.intellij.codeInsight.codeVision.CodeVisionProvider.
at com.intellij.codeInsight.codeVision.CodeVisionHost.collectPlaceholders(CodeVisionHost.kt:182)
at com.intellij.openapi.fileEditor.impl.text.PsiAwareTextEditorImpl.loadEditorInBackground(PsiAwareTextEditorImpl.java:70)
at com.intellij.openapi.fileEditor.impl.text.AsyncEditorLoader.lambda$scheduleLoading$0(AsyncEditorLoader.java:95)
at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:791)
at com.intellij.openapi.fileEditor.impl.text.AsyncEditorLoader.lambda$scheduleLoading$1(AsyncEditorLoader.java:93)
at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.insideReadAction(NonBlockingReadActionImpl.java:536)
at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.lambda$attemptComputation$3(NonBlockingReadActionImpl.java:501)
at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1154)
at com.intellij.openapi.progress.util.ProgressIndicatorUtils.lambda$runInReadActionWithWriteActionPriority$0(ProgressIndicatorUtils.java:75)
at com.intellij.openapi.progress.util.ProgressIndicatorUtils.runActionAndCancelBeforeWrite(ProgressIndicatorUtils.java:158)
at com.intellij.openapi.progress.util.ProgressIndicatorUtils.lambda$runWithWriteActionPriority$1(ProgressIndicatorUtils.java:115)
at com.intellij.openapi.progress.ProgressManager.lambda$runProcess$0(ProgressManager.java:66)
at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$2(CoreProgressManager.java:188)
at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$executeProcessUnderProgress$12(CoreProgressManager.java:608)
at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:683)
at com.intellij.openapi.progress.impl.CoreProgressManager.computeUnderProgress(CoreProgressManager.java:639)
at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:607)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:60)
at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:175)
at com.intellij.openapi.progress.ProgressManager.runProcess(ProgressManager.java:66)
at com.intellij.openapi.progress.util.ProgressIndicatorUtils.runWithWriteActionPriority(ProgressIndicatorUtils.java:112)
at com.intellij.openapi.progress.util.ProgressIndicatorUtils.runInReadActionWithWriteActionPriority(ProgressIndicatorUtils.java:75)
at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.attemptComputation(NonBlockingReadActionImpl.java:501)
at com.intellij.openapi.application.impl.NonBlockingReadActionImpl$Submission.lambda$transferToBgThread$1(NonBlockingReadActionImpl.java:408)
at com.intellij.util.concurrency.BoundedTaskExecutor.doRun(BoundedTaskExecutor.java:241)
at com.intellij.util.concurrency.BoundedTaskExecutor.access$200(BoundedTaskExecutor.java:31)
at com.intellij.util.concurrency.BoundedTaskExecutor$1.execute(BoundedTaskExecutor.java:214)
at com.intellij.util.ConcurrencyUtil.runUnderThreadName(ConcurrencyUtil.java:212)
at com.intellij.util.concurrency.BoundedTaskExecutor$1.run(BoundedTaskExecutor.java:203)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:702)
at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:699)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:699)
at java.base/java.lang.Thread.run(Thread.java:833)
my code:
class CodeVisionInlay : CodeVisionProvider<Unit>{
companion object {
internal const val id: String = "SmartChat"
}
override fun isAvailableFor(project: Project): Boolean {
return true
}
override fun precomputeOnUiThread(editor: Editor) {
}
override fun preparePreview(editor: Editor, file: PsiFile) {
}
override fun computeCodeVision(editor: Editor, uiData: Unit): CodeVisionState {
return runReadAction {
val project = editor.project ?: return@runReadAction CodeVisionState.READY_EMPTY
val document = editor.document
val file = PsiDocumentManager.getInstance(project).getPsiFile(document)
?: return@runReadAction CodeVisionState.READY_EMPTY
val lenses = ArrayList<Pair<TextRange, CodeVisionEntry>>()
val traverser = SyntaxTraverser.psiTraverser(file)
for (element in traverser.preOrderDfsTraversal()) {
//在每个方法代码块上镶嵌提示内容
if (element is PsiMethod) {
val textRange = InlayHintsUtils.getTextRangeWithoutLeadingCommentsAndWhitespaces(element)
val length = editor.document.textLength
val adjustedRange =
TextRange(Integer.min(textRange.startOffset, length), Integer.min(textRange.endOffset, length))
//嵌入提示的图标
val icon = ToolUtils.getImages("/images/pluginIcon.svg")//AllIcons.Vcs.Author
//点击嵌入提示触发的事件
val clickHandler = CodeAuthorClickHandler(element)
val entry = ClickableTextCodeVisionEntry("Sma", id, onClick = clickHandler, null, "Sma", "Sma", emptyList())
entry.showInMorePopup = false
lenses.add(adjustedRange to entry)
}
}
return@runReadAction CodeVisionState.Ready(lenses)
}
}
private class CodeAuthorClickHandler(val element: PsiElement) : (MouseEvent?, Editor) -> Unit {
override fun invoke(event: MouseEvent?, editor: Editor) {
if ((event != null) ) {
JBPopupFactory.getInstance().createListPopup(
PluginDartIconActioinMenuList(
element = element
)
).show(RelativePoint(event.locationOnScreen))
}
}
}
override val name: String
get() = "SmartChat"
override val relativeOrderings: List<CodeVisionRelativeOrdering>
get() = emptyList()
override val defaultAnchor: CodeVisionAnchorKind
get() = CodeVisionAnchorKind.NearScroll
override val id: String
get() = Companion.id
data class PluginDartIconActionMenuItem(val key:String,val title: String, val type: String, val icon: Icon)
class PluginDartIconActioinMenuList(val element: PsiElement) : BaseListPopupStep<PluginDartIconActionMenuItem>() {
//按钮组列表
private val menus = getMenus()
init {
super.init(element.text, menus, menus.map { it.icon })
}
override fun getTextFor(value: PluginDartIconActionMenuItem?): String {
return value?.title ?: "未知选项"
}
override fun onChosen(selectedValue: PluginDartIconActionMenuItem?, finalChoice: Boolean): PopupStep<*>? {
val key = selectedValue?.key;
val title = selectedValue?.title
val project = PsiManager.getInstance(element.getProject()).project
val service = project.service<MyProjectService>()
if(service.jbCefBrowser == null) {
val notificationGroup = NotificationGroup("AISE.Notification", NotificationDisplayType.BALLOON, true)
val notify = notificationGroup.createNotification("Please open SmartChat chat window before using SmartChat context menu(Menu->View->Tool Window->SmartChat). ", NotificationType.WARNING)
Notifications.Bus.notify(notify)
println("jbCefBrowser is null !")
}
val selectedText = element.text;
val msgJSON = JSONObject()
msgJSON.put("type","sendCodeContextMessage.jetBrains")
msgJSON.put("content","")
msgJSON.put("id",System.currentTimeMillis())
msgJSON.put("key",key)
msgJSON.put("visibleText","")
//代码块内容
msgJSON.put("selectedContent", selectedText)
msgJSON.put("triggerSource","ext.contextMenu")
val data = JSONArray()
msgJSON["selection"] = data
if (selectedText !== null ) {
service.jbCefBrowser!!.cefBrowser.mainFrame.executeJavaScript("window.pluginCallBrowser(${msgJSON.toJSONString()})",
service.jbCefBrowser!!.cefBrowser.mainFrame.url, 0) //JSONStyle.NO_COMPRESS
}
else {
val notificationGroup = NotificationGroup("AISE.Notification", NotificationDisplayType.BALLOON, true)
val notify = notificationGroup.createNotification("No code block selected for "+title, NotificationType.INFORMATION)
Notifications.Bus.notify(notify)
}
return super.onChosen(selectedValue, finalChoice)
}
fun getMenus(): List<PluginDartIconActionMenuItem> {
val listOfValues = mutableListOf<PluginDartIconActionMenuItem>()
//提示词菜单,后期会通过接口获取
val jsonArrayString = """
[
{
"key": "Dev_Code_Explain", //提示词唯一标识
"text": "explain", //提示词文本
"description": "New York", //提示词描述
"actionClassName":"ToolbarDecorator", //图标组
"icon":"Export" //图标组下其中的一个元素
},
{
"key": "Dev_Code_Review",
"text": "review",
"description": "review",
"actionClassName":"Nodes",
"icon":"Field"
},
{
"key": "Dev_Code_GenUT",
"text": "generate unit tests",
"description": "generate unit tests",
"actionClassName":"Nodes",
"icon":"TestSourceFolder"
}
]
"""
val gson = Gson()
// 使用TypeToken创建一个Type,以便Gson知道如何解析List<Map>
val listType = object : TypeToken<List<Map<String, String>>>() {}.type
// 将JSON字符串转换为List<Map>
val list: List<Map<String, String>> = gson.fromJson(jsonArrayString, listType)
for (element in list) {
val firstMap: Map<String, String> = element
val key = firstMap["key"].toString()
val text = firstMap["text"].toString()
//图片组
val actionClassName = firstMap["actionClassName"].toString()
//图片组下的一个图标
val icon = firstMap["icon"].toString()
//从idea图标库中获取图标
val iconImage = ToolUtils.getIconName(actionClassName,icon)
//动态添加提示词菜单
listOfValues.add(
PluginDartIconActionMenuItem(
key = key,
title = text,
type = "navToPub",
icon = iconImage
))
}
return listOfValues
}
}
}
Please note, this API is marked as Experimental and may change at any time https://plugins.jetbrains.com/docs/intellij/verifying-plugin-compatibility.html#unstable-api
What is the target IDE platform you're building your plugin against? It should be the lowest supported IDE version.
Yes, I know that's unstable. But that's not what I meant.
When a higher version of the plug-in is installed into a lower version of 'IDEA', what should be done so that the original functions of the plug-in are not affected?
There is nothing you can do to prevent such errors, other than following the recommendation of building against the lowest supported IDE version (assuming API will be kept backwards-compatible, which might not be the case for this API). You can use Plugin Verifier locally to check compliance https://plugins.jetbrains.com/docs/intellij/verifying-plugin-compatibility.html.
Alternatively, you can target and build distinct versions of your plugin for each IDE version where there are breaking changes.
Can I do this? Make a judgment on the version number of 'IntelliJ IDEA' in the plug-in. If 'IntelliJ IDEA' is a new version, execute the new features in the plug-in. If 'IntelliJ IDEA' is an old version, the code for new features in the plug-in will not be executed. Keep the original functionality of the plug-in unaffected. Is this possible?
No, you need to build and release distinct versions of your plugin -- each targeting exact range of supported IDE version(s).
Okay, thank you.I'll think of other methods.