mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[kotlin-dfa] Avoid capturing context in getVariablesChangedInNestedFunctions
Fixes KTIJ-29069 K2: IDE K2: "Incorrect CachedValue in class KtVariableDescriptor" GitOrigin-RevId: 6b2cf38b2b519a44a4498aae2ba2ece659c22f0f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
8c62f85002
commit
0ad41db427
+31
-26
@@ -6,7 +6,6 @@ import com.intellij.codeInspection.dataFlow.jvm.descriptors.JvmVariableDescripto
|
||||
import com.intellij.codeInspection.dataFlow.types.DfType
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaValueFactory
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
@@ -28,16 +27,21 @@ class KtVariableDescriptor(val module: KtModule,
|
||||
val type: DfType,
|
||||
val hash: Int) : JvmVariableDescriptor() {
|
||||
val stable: Boolean by lazy {
|
||||
analyze(module) {
|
||||
when(val result = analyze(module) {
|
||||
val symbol = pointer.restoreSymbol() ?: return@analyze false
|
||||
if (symbol is KtValueParameterSymbol || symbol is KtEnumEntrySymbol) return@analyze true
|
||||
if (symbol is KtPropertySymbol) return@analyze symbol.isVal
|
||||
if (symbol is KtLocalVariableSymbol) {
|
||||
if (symbol.isVal) return@analyze true
|
||||
val psiElement = symbol.psi?.parent
|
||||
return@analyze psiElement == null || !getVariablesChangedInNestedFunctions(psiElement).contains(this@KtVariableDescriptor)
|
||||
val psiElement = symbol.psi?.parent as? KtElement
|
||||
if (psiElement == null) return@analyze true
|
||||
return@analyze psiElement
|
||||
}
|
||||
if (symbol is KtValueParameterSymbol || symbol is KtEnumEntrySymbol || symbol is KtReceiverParameterSymbol) return@analyze true
|
||||
if (symbol is KtPropertySymbol) return@analyze symbol.isVal
|
||||
return@analyze false
|
||||
}) {
|
||||
is Boolean -> result
|
||||
is KtElement -> !getVariablesChangedInNestedFunctions(result).contains(this@KtVariableDescriptor)
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,32 +93,33 @@ class KtVariableDescriptor(val module: KtModule,
|
||||
this.name.hashCode())
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
private fun getVariablesChangedInNestedFunctions(parent: PsiElement): Set<KtVariableDescriptor> =
|
||||
private fun getVariablesChangedInNestedFunctions(parent: KtElement): Set<KtVariableDescriptor> =
|
||||
CachedValuesManager.getProjectPsiDependentCache(parent) { scope ->
|
||||
val result = hashSetOf<KtVariableDescriptor>()
|
||||
PsiTreeUtil.processElements(scope) { e ->
|
||||
if (e is KtSimpleNameExpression && e.readWriteAccess(false).isWrite) {
|
||||
val target = e.mainReference.resolve()
|
||||
if (target is KtProperty && target.isLocal && PsiTreeUtil.isAncestor(parent, target, true)) {
|
||||
var parentScope : KtFunction?
|
||||
var context = e
|
||||
while(true) {
|
||||
parentScope = PsiTreeUtil.getParentOfType(context, KtFunction::class.java)
|
||||
val maybeLambda = parentScope?.parent as? KtLambdaExpression
|
||||
val maybeCall = (maybeLambda?.parent as? KtLambdaArgument)?.parent as? KtCallExpression
|
||||
if (maybeCall != null && getInlineableLambda(maybeCall)?.lambda == maybeLambda) {
|
||||
context = maybeCall
|
||||
continue
|
||||
analyze(scope) {
|
||||
PsiTreeUtil.processElements(scope) { e ->
|
||||
if (e is KtSimpleNameExpression && e.readWriteAccess(false).isWrite) {
|
||||
val target = e.mainReference.resolve()
|
||||
if (target is KtProperty && target.isLocal && PsiTreeUtil.isAncestor(scope, target, true)) {
|
||||
var parentScope: KtFunction?
|
||||
var context = e
|
||||
while (true) {
|
||||
parentScope = PsiTreeUtil.getParentOfType(context, KtFunction::class.java)
|
||||
val maybeLambda = parentScope?.parent as? KtLambdaExpression
|
||||
val maybeCall = (maybeLambda?.parent as? KtLambdaArgument)?.parent as? KtCallExpression
|
||||
if (maybeCall != null && getInlineableLambda(maybeCall)?.lambda == maybeLambda) {
|
||||
context = maybeCall
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
if (parentScope != null && PsiTreeUtil.isAncestor(scope, parentScope, true)) {
|
||||
result.add(target.getVariableSymbol().variableDescriptor())
|
||||
}
|
||||
break
|
||||
}
|
||||
if (parentScope != null && PsiTreeUtil.isAncestor(parent, parentScope, true)) {
|
||||
result.add(target.getVariableSymbol().variableDescriptor())
|
||||
}
|
||||
}
|
||||
return@processElements true
|
||||
}
|
||||
return@processElements true
|
||||
}
|
||||
return@getProjectPsiDependentCache result
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user