From cf175fb5da7b0a48aac8cb984affdd9453535888 Mon Sep 17 00:00:00 2001 From: Maksim Zuev Date: Fri, 13 Jun 2025 12:03:21 +0200 Subject: [PATCH] [debugger] Convert DfaAssistProvider to Kotlin GitOrigin-RevId: ce66166e4fea23a31231c657969df36ff8ed6d0d --- .../engine/dfaassist/DfaAssistProvider.kt | 125 ++++++++++-------- .../engine/dfaassist/JdiValueInfo.java | 4 +- 2 files changed, 70 insertions(+), 59 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/dfaassist/DfaAssistProvider.kt b/java/debugger/impl/src/com/intellij/debugger/engine/dfaassist/DfaAssistProvider.kt index ecf65a0e9a8b..3ac7f5ca92dd 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/dfaassist/DfaAssistProvider.kt +++ b/java/debugger/impl/src/com/intellij/debugger/engine/dfaassist/DfaAssistProvider.kt @@ -1,50 +1,32 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.debugger.engine.dfaassist; +package com.intellij.debugger.engine.dfaassist -import com.intellij.codeInspection.dataFlow.TypeConstraint; -import com.intellij.codeInspection.dataFlow.TypeConstraints; -import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; -import com.intellij.debugger.engine.evaluation.EvaluateException; -import com.intellij.debugger.jdi.StackFrameProxyEx; -import com.intellij.lang.LanguageExtension; -import com.intellij.psi.PsiElement; -import com.sun.jdi.*; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import com.intellij.codeInspection.dataFlow.TypeConstraint +import com.intellij.codeInspection.dataFlow.value.DfaVariableValue +import com.intellij.debugger.engine.evaluation.EvaluateException +import com.intellij.debugger.jdi.StackFrameProxyEx +import com.intellij.lang.LanguageExtension +import com.intellij.psi.PsiElement +import com.sun.jdi.* /** * Language specific helpers to implement DFAAssist (for JVM languages only) */ -public interface DfaAssistProvider { - LanguageExtension EP_NAME = new LanguageExtension<>("com.intellij.debugger.dfaAssistProvider"); - - /** - * A sentinel to represent null constant. - * - * @see #getJdiValueForDfaVariable(StackFrameProxyEx, DfaVariableValue, PsiElement) - */ - Value NullConst = new Value() { - @Override - public VirtualMachine virtualMachine() { return null; } - - @Override - public Type type() { return null; } - - @Override - public String toString() { return "null"; } - }; - +interface DfaAssistProvider { /** * Represents a 'virtual' boxed value which in fact does not exist in the VM memory. * Can be useful to virtually undo optimizations like instantiation of inline function generic parameter with a primitive value in Kotlin. * * @param value a primitive value to box - * @param type type of the box (e.g. {@code java.lang.Integer}) + * @param type type of the box (e.g. `java.lang.Integer`) */ - record BoxedValue(@NotNull Value value, @NotNull ReferenceType type) implements Value { - @Override - public VirtualMachine virtualMachine() { - return value.virtualMachine(); + data class BoxedValue(val value: Value, val type: ReferenceType) : Value { + override fun virtualMachine(): VirtualMachine? { + return value.virtualMachine() + } + + override fun type(): Type { + return type } } @@ -56,7 +38,7 @@ public interface DfaAssistProvider { * @return true if debugger location likely matches to the editor location; * false if definitely doesn't match (in this case, DFA Assist will be turned off) */ - boolean locationMatches(@NotNull PsiElement element, @NotNull Location location); + fun locationMatches(element: PsiElement, location: Location): Boolean /** * @param element psi element the debugger state points at @@ -64,46 +46,75 @@ public interface DfaAssistProvider { * Currently, at this anchor interpretation stack must be empty. May return null if DFA assist cannot start * at current context. */ - @Nullable PsiElement getAnchor(@NotNull PsiElement element); + fun getAnchor(element: PsiElement): PsiElement? /** - * @param anchor anchor returned by {@link #getAnchor(PsiElement)} call + * @param anchor anchor returned by [.getAnchor] call * @return code block to analyze via DFA assist (e.g., method body, loop body, etc.) */ - @Nullable PsiElement getCodeBlock(@NotNull PsiElement anchor); + fun getCodeBlock(anchor: PsiElement): PsiElement? /** * @param proxy proxy to create JDI values * @param var DfaVariableValue to find value for - * @param anchor anchor previously returned by {@link #getAnchor(PsiElement)} call, where analysis takes place + * @param anchor anchor previously returned by [.getAnchor] call, where analysis takes place * @return JDI value for a variable; null if value is not known; NullConst if value is known to be null - * (use {@link #wrap(Value)} utility method for this purpose). + * (use [.wrap] utility method for this purpose). * @throws EvaluateException if proxy throws */ - @Nullable Value getJdiValueForDfaVariable(@NotNull StackFrameProxyEx proxy, - @NotNull DfaVariableValue var, - @NotNull PsiElement anchor) throws EvaluateException; + @Throws(EvaluateException::class) + fun getJdiValueForDfaVariable( + proxy: StackFrameProxyEx, + `var`: DfaVariableValue, + anchor: PsiElement, + ): Value? /** * @return a new listener to attach to DFA session that will gather DFAAssist hints */ - @NotNull DebuggerDfaListener createListener(); + fun createListener(): DebuggerDfaListener /** - * @param anchor a context PsiElement previously returned by {@link #getAnchor(PsiElement)} + * @param anchor a context PsiElement previously returned by [.getAnchor] * @param jvmClassName JVM class name like "java/lang/String" - * @return a {@link TypeConstraint} suitable for the current language; - * {@link TypeConstraints#TOP} if class is not resolved + * @return a [TypeConstraint] suitable for the current language; + * [com.intellij.codeInspection.dataFlow.TypeConstraints.TOP] if class is not resolved */ - @NotNull TypeConstraint constraintFromJvmClassName(@NotNull PsiElement anchor, @NotNull String jvmClassName); + fun constraintFromJvmClassName(anchor: PsiElement, jvmClassName: String): TypeConstraint - /** - * A helper method to implement {@link #getJdiValueForDfaVariable(StackFrameProxyEx, DfaVariableValue, PsiElement)} - * - * @param value value to wrap - * @return NullConst if value is null; value otherwise - */ - static @NotNull Value wrap(@Nullable Value value) { - return value == null ? NullConst : value; + companion object { + /** + * A helper method to implement [.getJdiValueForDfaVariable] + * + * @param value value to wrap + * @return NullConst if value is null; value otherwise + */ + @JvmStatic + fun wrap(value: Value?): Value { + return value ?: NullConst + } + + @JvmField + val EP_NAME: LanguageExtension = LanguageExtension("com.intellij.debugger.dfaAssistProvider") + + /** + * A sentinel to represent null constant. + * + * @see .getJdiValueForDfaVariable + */ + @JvmField + val NullConst: Value = object : Value { + override fun virtualMachine(): VirtualMachine? { + return null + } + + override fun type(): Type? { + return null + } + + override fun toString(): String { + return "null" + } + } } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/dfaassist/JdiValueInfo.java b/java/debugger/impl/src/com/intellij/debugger/engine/dfaassist/JdiValueInfo.java index 0eda53702cb7..4d933701f139 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/dfaassist/JdiValueInfo.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/dfaassist/JdiValueInfo.java @@ -108,9 +108,9 @@ interface JdiValueInfo { return new StringConstant(stringReference.value()); } if (value instanceof DfaAssistProvider.BoxedValue boxedValue) { - DfConstantType wrappedConstant = primitiveConstant(boxedValue.value()); + DfConstantType wrappedConstant = primitiveConstant(boxedValue.getValue()); if (wrappedConstant != null) { - return new ObjectWithSpecialField(boxedValue.type(), SpecialField.UNBOX, new PrimitiveConstant(wrappedConstant)); + return new ObjectWithSpecialField(boxedValue.getType(), SpecialField.UNBOX, new PrimitiveConstant(wrappedConstant)); } } if (value instanceof ObjectReference ref) {