mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[debugger] Convert DfaAssistProvider to Kotlin
GitOrigin-RevId: ce66166e4fea23a31231c657969df36ff8ed6d0d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
7f143cd6f6
commit
cf175fb5da
+68
-57
@@ -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<DfaAssistProvider> 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<DfaAssistProvider?> = LanguageExtension<DfaAssistProvider?>("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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user