fix: NPE caused by lookup element sorter

This commit is contained in:
Carl-Robert Linnupuu 2024-12-03 17:10:46 +00:00
parent 3c84f2e99c
commit cdb0d7b7ad
3 changed files with 66 additions and 30 deletions

View file

@ -0,0 +1,46 @@
package ee.carlrobert.codegpt.refactorings
import com.intellij.openapi.util.Key
import com.intellij.psi.PsiElement
import com.intellij.psi.codeStyle.SuggestedNameInfo
import com.intellij.psi.tree.IElementType
import com.intellij.psi.util.elementType
import com.intellij.refactoring.rename.NameSuggestionProvider
class DefaultNameSuggestionProvider : NameSuggestionProvider {
companion object {
val KEY = Key.create<Boolean>("codegpt.refactorings.renameAllowed")
}
override fun getSuggestedNames(
element: PsiElement,
nameSuggestionContext: PsiElement?,
result: MutableSet<String>
): SuggestedNameInfo {
element.elementType?.let {
if (PSIMethodMapping.contains(it)) {
element.putUserData(KEY, true)
}
}
return SuggestedNameInfo.NULL_INFO
}
private enum class PSIMethodMapping(val types: List<String>) {
GO(listOf("FILE", "METHOD_DECLARATION|FUNCTION_DECLARATION")),
JAVA(listOf("java.FILE", "METHOD")),
PY(listOf("FILE", "Py:FUNCTION_DECLARATION")),
JAVASCRIPT(listOf("JS:FUNCTION_DECLARATION", "JS:TYPESCRIPT_FUNCTION")),
CS(listOf("FILE", "DUMMY_TYPE_DECLARATION", "DUMMY_BLOCK")),
PHP(listOf("FILE", "Class method|function|Function")),
KOTLIN(listOf("FUN")),
DEFAULT(listOf("FILE", "METHOD_DECLARATION"));
companion object {
fun contains(type: IElementType): Boolean {
return entries.any { it.types.contains(type.toString()) }
}
}
}
}

View file

@ -1,6 +1,7 @@
package ee.carlrobert.codegpt.completions
package ee.carlrobert.codegpt.refactorings
import com.intellij.codeInsight.completion.PrefixMatcher
import com.intellij.codeInsight.completion.PrioritizedLookupElement
import com.intellij.codeInsight.lookup.Lookup
import com.intellij.codeInsight.lookup.LookupElementBuilder
import com.intellij.codeInsight.lookup.LookupManagerListener
@ -10,10 +11,10 @@ import com.intellij.openapi.application.runInEdt
import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.components.service
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.psi.tree.IElementType
import com.intellij.psi.util.PsiUtilCore
import ee.carlrobert.codegpt.CodeGPTKeys.IS_PROMPT_TEXT_FIELD_DOCUMENT
import ee.carlrobert.codegpt.Icons
import ee.carlrobert.codegpt.completions.CompletionRequestService
import ee.carlrobert.codegpt.completions.LookupCompletionParameters
import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings
import ee.carlrobert.codegpt.ui.OverlayUtil
import ee.carlrobert.llm.client.codegpt.response.CodeGPTException
@ -22,7 +23,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
class MethodNameCompletionLookupListener : LookupManagerListener {
class RenameCompletionLookupListener : LookupManagerListener {
companion object {
private val logger = thisLogger()
@ -43,8 +44,8 @@ class MethodNameCompletionLookupListener : LookupManagerListener {
}
newLookup.psiElement?.context?.let { context ->
val elementType = PsiUtilCore.getElementType(context)
if (PSIMethodMapping.contains(elementType)) {
val renamingEnabled = context.getUserData(DefaultNameSuggestionProvider.KEY) ?: false
if (renamingEnabled) {
val selection = runReadAction { context.text }
scope.launch {
try {
@ -72,34 +73,22 @@ class MethodNameCompletionLookupListener : LookupManagerListener {
.dropLastWhile { it.isEmpty() }
.toTypedArray()
for (value in values) {
runInEdt {
lookup.addItem(
runInEdt {
for (value in values) {
val prioritizedLookupElement = PrioritizedLookupElement.withPriority(
LookupElementBuilder
.create(value)
.withIcon(Icons.DefaultSmall),
PrefixMatcher.ALWAYS_TRUE
.withIcon(Icons.DefaultSmall)
.withLookupString(value),
1.0
)
if (!lookup.isLookupDisposed) {
lookup.addItem(prioritizedLookupElement, PrefixMatcher.ALWAYS_TRUE)
}
}
if (!lookup.isLookupDisposed) {
lookup.refreshUi(true, true)
}
}
}
private enum class PSIMethodMapping(val types: List<String>) {
GO(listOf("FILE", "METHOD_DECLARATION|FUNCTION_DECLARATION")),
JAVA(listOf("java.FILE", "METHOD")),
PY(listOf("FILE", "Py:FUNCTION_DECLARATION")),
JAVASCRIPT(listOf("JS:FUNCTION_DECLARATION", "JS:TYPESCRIPT_FUNCTION")),
CS(listOf("FILE", "DUMMY_TYPE_DECLARATION", "DUMMY_BLOCK")),
PHP(listOf("FILE", "Class method|function|Function")),
KOTLIN(listOf("FUN")),
DEFAULT(listOf("FILE", "METHOD_DECLARATION"));
companion object {
fun contains(type: IElementType): Boolean {
return entries.any { it.types.contains(type.toString()) }
}
}
}
}

View file

@ -16,7 +16,7 @@
<projectListeners>
<listener topic="com.intellij.codeInsight.lookup.LookupManagerListener"
class="ee.carlrobert.codegpt.completions.MethodNameCompletionLookupListener"/>
class="ee.carlrobert.codegpt.refactorings.RenameCompletionLookupListener"/>
<listener topic="com.intellij.openapi.wm.ex.ToolWindowManagerListener"
class="ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowListener"/>
</projectListeners>
@ -79,6 +79,7 @@
<notificationGroup id="CodeGPT Notification Group Sticky" displayType="STICKY_BALLOON" key="notification.group.sticky.name"/>
<statusBarWidgetFactory order="first" id="ee.carlrobert.codegpt.statusbar.widget"
implementation="ee.carlrobert.codegpt.statusbar.CodeGPTStatusBarWidgetFactory"/>
<nameSuggestionProvider implementation="ee.carlrobert.codegpt.refactorings.DefaultNameSuggestionProvider"/>
</extensions>
<resource-bundle>messages.codegpt</resource-bundle>