Skip to content

Commit

Permalink
feature: implement VarHandle type analysis support (#95)
Browse files Browse the repository at this point in the history
  • Loading branch information
SirYwell committed Jun 19, 2024
1 parent bafda4a commit 96d719e
Show file tree
Hide file tree
Showing 17 changed files with 263 additions and 147 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import com.intellij.psi.PsiParameterList
import com.intellij.psi.PsiReferenceExpression
import com.intellij.refactoring.suggested.endOffset
import com.intellij.refactoring.suggested.startOffset
import de.sirywell.handlehints.type.BotSignature
import de.sirywell.handlehints.type.TopSignature
import de.sirywell.handlehints.type.*

class MethodTypeInlayHintsCollector : SharedBypassCollector {

Expand All @@ -33,7 +32,10 @@ class MethodTypeInlayHintsCollector : SharedBypassCollector {
val typeData = TypeData.forFile(element.containingFile)
val type = typeData[element] ?: return
// don't print
if (type.signature is TopSignature || type.signature is BotSignature) {
if (type is MethodHandleType && (type.signature is TopSignature || type.signature is BotSignature)) {
return
}
if (type is TopVarHandleType || type is BotVarHandleType) {
return
}
sink.addPresentation(InlineInlayPosition(pos, belongsToBefore), hasBackground = true) {
Expand Down
9 changes: 6 additions & 3 deletions src/main/kotlin/de/sirywell/handlehints/TypeData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import com.intellij.psi.PsiFile
import com.intellij.psi.util.CachedValuesManager
import de.sirywell.handlehints.dfa.MhTypeProvider
import de.sirywell.handlehints.type.MethodHandleType

Check warning on line 9 in src/main/kotlin/de/sirywell/handlehints/TypeData.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused import directive

Unused import directive
import de.sirywell.handlehints.type.TypeLatticeElement

class TypeData: ModificationTracker by ModificationTracker.NEVER_CHANGED {
class TypeData : ModificationTracker by ModificationTracker.NEVER_CHANGED {
companion object {
fun forFile(file: PsiFile): TypeData {
return CachedValuesManager.getManager(file.project)
Expand All @@ -21,11 +22,13 @@ class TypeData: ModificationTracker by ModificationTracker.NEVER_CHANGED {
)
}
}
private val map = mutableMapOf<PsiElement, MethodHandleType>()

private val map = mutableMapOf<PsiElement, TypeLatticeElement<*>>()
private val problems = mutableMapOf<PsiElement, (ProblemsHolder) -> Unit>()

inline operator fun <reified T : TypeLatticeElement<*>> invoke(element: PsiElement) = get(element) as? T
operator fun get(element: PsiElement) = map[element]
operator fun set(element: PsiElement, type: MethodHandleType) {
operator fun set(element: PsiElement, type: TypeLatticeElement<*>) {
map[element] = type
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,24 @@ package de.sirywell.handlehints.dfa
import com.intellij.openapi.util.RecursionManager.doPreventingRecursion
import com.intellij.psi.*
import com.intellij.psi.util.childrenOfType
import de.sirywell.handlehints.type.BotSignature
import de.sirywell.handlehints.type.MethodHandleType

class MethodHandleTypeResolver(private val ssaAnalyzer: SsaAnalyzer, private val block: SsaConstruction.Block) :
import de.sirywell.handlehints.type.TypeLatticeElement
import kotlin.reflect.KClass
import kotlin.reflect.cast

class HandleTypeResolver<T : TypeLatticeElement<T>>(
private val ssaAnalyzer: SsaAnalyzer,
private val block: SsaConstruction.Block,
private val bot: T,
private val clazz: KClass<T>
) :
JavaRecursiveElementVisitor() {

var result: MethodHandleType? = null
var result: T? = null
private set

override fun visitSwitchExpression(expression: PsiSwitchExpression) {
val rules = (expression.body ?: return).childrenOfType<PsiSwitchLabeledRuleStatement>()
var r = MethodHandleType(BotSignature)
var r = bot
for (rule in rules) {
rule.body?.accept(this) ?: continue
r = r.join(result ?: continue)
Expand All @@ -31,21 +37,24 @@ class MethodHandleTypeResolver(private val ssaAnalyzer: SsaAnalyzer, private val
}

override fun visitConditionalExpression(expression: PsiConditionalExpression) {
val then = calculateType(expression.thenExpression ?: return)
?: MethodHandleType(BotSignature)
val elsa = calculateType(expression.elseExpression ?: return)
?: MethodHandleType(BotSignature)
val then = calculateType(expression.thenExpression ?: return) ?: bot
val elsa = calculateType(expression.elseExpression ?: return) ?: bot
result = then.join(elsa)
}

override fun visitParenthesizedExpression(expression: PsiParenthesizedExpression) {
result = calculateType(expression.expression ?: return)
}

private fun calculateType(expression: PsiExpression): MethodHandleType? {
return ssaAnalyzer.typeData[expression]
// SsaAnalyzer might call us again. Prevent SOE
?: doPreventingRecursion(expression, true) { ssaAnalyzer.resolveMhType(expression, block) }
private fun calculateType(expression: PsiExpression): T? {
val t: TypeLatticeElement<*> = (ssaAnalyzer.typeData[expression]
// SsaAnalyzer might call us again. Prevent SOE
?: doPreventingRecursion(expression, true) { ssaAnalyzer.resolveType(expression, block) })
?: return null
if (clazz.isInstance(t)) {
return clazz.cast(t)
}
return null
}

}
Loading

0 comments on commit 96d719e

Please sign in to comment.