[spring debugger] IDEA-357571 Provide icon to show in the additional context element completion

GitOrigin-RevId: 91839d39666ea5fb617476592fe0efd5e4d36d65
This commit is contained in:
Maksim Zuev
2024-11-14 18:37:43 +00:00
committed by intellij-monorepo-bot
parent ee51678cfc
commit a624b1e931
5 changed files with 31 additions and 16 deletions
@@ -3,20 +3,13 @@ package com.intellij.debugger.engine.evaluation
import com.intellij.debugger.impl.DebuggerUtilsEx
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.JavaRecursiveElementVisitor
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiLocalVariable
import com.sun.jdi.Value
import java.util.regex.Pattern
internal class JavaEvaluationContextWrapper : EvaluationContextWrapper {
companion object {
@JvmField
val SYNTHETIC_VARIABLE_VALUE_KEY = Key.create<(EvaluationContext) -> Value>("SYNTHETIC_VARIABLE_VALUE_KEY")
}
override fun wrapContext(project: Project, context: PsiElement?, additionalElements: List<AdditionalContextElement>): PsiElement? {
if (additionalElements.isEmpty()) return context
val elementsByName = additionalElements.groupBy { it.name }.mapValues { (_, v) -> v[0] }
@@ -28,10 +21,8 @@ internal class JavaEvaluationContextWrapper : EvaluationContextWrapper {
fragment.accept(object : JavaRecursiveElementVisitor() {
override fun visitLocalVariable(variable: PsiLocalVariable) {
val name = variable.name
val computeValue = elementsByName[name]?.value
if (computeValue != null) {
variable.putUserData(SYNTHETIC_VARIABLE_VALUE_KEY, computeValue)
}
val element = elementsByName[name] ?: return
variable.putUserData(AdditionalContextProvider.ADDITIONAL_CONTEXT_ELEMENT_KEY, element)
}
})
return fragment
@@ -57,7 +57,7 @@ class MarkedObjectAdditionalContextProvider implements AdditionalContextProvider
try {
labelName += CodeFragmentFactoryContextWrapper.DEBUG_LABEL_SUFFIX;
Type type = objectRef.type();
result.add(new AdditionalContextElement(labelName, type.signature(), type.name(), __ -> objectRef));
result.add(new AdditionalContextElement(labelName, type.signature(), type.name(), /* icon */ null, __ -> objectRef));
}
catch (ObjectCollectedException e) {
//it.remove();
@@ -819,12 +819,12 @@ public final class EvaluatorBuilderImpl implements EvaluatorBuilder {
PsiElement element = resolveResult.getElement();
if (element instanceof PsiLocalVariable || element instanceof PsiParameter) {
var computeSyntheticValue = element.getUserData(JavaEvaluationContextWrapper.SYNTHETIC_VARIABLE_VALUE_KEY);
if (computeSyntheticValue != null) {
var contextElement = element.getUserData(AdditionalContextProvider.getADDITIONAL_CONTEXT_ELEMENT_KEY());
if (contextElement != null) {
myResult = new Evaluator() {
@Override
public Object evaluate(EvaluationContextImpl context) {
return computeSyntheticValue.invoke(context);
return contextElement.getValue().invoke(context);
}
};
return;
@@ -1,11 +1,16 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.debugger.engine.evaluation
import com.intellij.debugger.engine.evaluation.AdditionalContextProvider
import com.intellij.ide.IconProvider
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key
import com.intellij.psi.PsiElement
import com.sun.jdi.Value
import org.jetbrains.annotations.ApiStatus
import javax.swing.Icon
/**
* Language-specific wrapper that can add variables into an evaluation context.
@@ -24,6 +29,9 @@ interface AdditionalContextProvider {
companion object {
private val EP_NAME = ExtensionPointName.create<AdditionalContextProvider>("com.intellij.debugger.additionalContextProvider")
@JvmStatic
@ApiStatus.Internal
val ADDITIONAL_CONTEXT_ELEMENT_KEY = Key.create<AdditionalContextElement>("ADDITIONAL_CONTEXT_ELEMENT_KEY")
@JvmStatic
fun getAllAdditionalContextElements(project: Project, context: PsiElement?): List<AdditionalContextElement> {
@@ -43,6 +51,21 @@ interface AdditionalContextProvider {
* @property jvmSignature Object type signature, for example `Ljava/lang/Object;`.
* @property jvmTypeName Object type name, for example `java.lang.Object`.
* @property value A lambda function returning a [Value] type used for evaluation.
* @property icon Icon to be shown during completion of the element or null, if no custom icon is needed.
*
* Not all languages support icon rendering! Currently only supported for Java.
*/
@ApiStatus.Internal
data class AdditionalContextElement(val name: String, val jvmSignature: String, val jvmTypeName: String, val value: (EvaluationContext) -> Value)
data class AdditionalContextElement(val name: String, val jvmSignature: String, val jvmTypeName: String,
val icon: Icon? = null, val value: (EvaluationContext) -> Value)
/**
* This icon provider works only for elements with [AdditionalContextProvider.ADDITIONAL_CONTEXT_ELEMENT_KEY] set,
* so it should be only elements suggested in evaluation.
*/
private class AdditionalContextIconProvider : IconProvider(), DumbAware {
override fun getIcon(element: PsiElement, flags: Int): Icon? {
val contextElement = element.getUserData(AdditionalContextProvider.ADDITIONAL_CONTEXT_ELEMENT_KEY) ?: return null
return contextElement.icon
}
}