Extract some cfg utilities into separate files

These utilties are used not only within CFG, but from the frontend and
idea as well. Therefore upon extraction of CFG into another module,
these two new files will remain in 'frontend'.
This commit is contained in:
Alexander Udalov
2020-03-15 20:40:34 +01:00
committed by Alexander Udalov
parent a9b9cced15
commit 5ad0033d42
17 changed files with 96 additions and 82 deletions
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.codegen.coroutines
import com.intellij.util.ArrayUtil import com.intellij.util.ArrayUtil
import org.jetbrains.kotlin.backend.common.CodegenUtil import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype
import org.jetbrains.kotlin.cfg.index
import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure import org.jetbrains.kotlin.codegen.binding.CalculatedClosure
import org.jetbrains.kotlin.codegen.binding.CodegenBinding import org.jetbrains.kotlin.codegen.binding.CodegenBinding
@@ -35,6 +34,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.indexOrMinusOne
import org.jetbrains.kotlin.resolve.isInlineClassType import org.jetbrains.kotlin.resolve.isInlineClassType
import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
@@ -263,7 +263,7 @@ class CoroutineCodegenForLambda private constructor(
private fun ParameterDescriptor.isUnused(): Boolean = private fun ParameterDescriptor.isUnused(): Boolean =
originalSuspendFunctionDescriptor is AnonymousFunctionDescriptor && originalSuspendFunctionDescriptor is AnonymousFunctionDescriptor &&
bindingContext[BindingContext.SUSPEND_LAMBDA_PARAMETER_USED, originalSuspendFunctionDescriptor to index()] != true bindingContext[BindingContext.SUSPEND_LAMBDA_PARAMETER_USED, originalSuspendFunctionDescriptor to indexOrMinusOne()] != true
private val generateErasedCreate: Boolean = allFunctionParameters().size <= 1 private val generateErasedCreate: Boolean = allFunctionParameters().size <= 1
@@ -34,18 +34,6 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.types.expressions.OperatorConventions
interface LeakingThisDescriptor {
val classOrObject: KtClassOrObject
data class PropertyIsNull(val property: PropertyDescriptor, override val classOrObject: KtClassOrObject) : LeakingThisDescriptor
data class NonFinalClass(val klass: ClassDescriptor, override val classOrObject: KtClassOrObject) : LeakingThisDescriptor
data class NonFinalProperty(val property: PropertyDescriptor, override val classOrObject: KtClassOrObject) : LeakingThisDescriptor
data class NonFinalFunction(val function: FunctionDescriptor, override val classOrObject: KtClassOrObject) : LeakingThisDescriptor
}
class ConstructorConsistencyChecker private constructor( class ConstructorConsistencyChecker private constructor(
private val classOrObject: KtClassOrObject, private val classOrObject: KtClassOrObject,
private val classDescriptor: ClassDescriptor, private val classDescriptor: ClassDescriptor,
@@ -36,7 +36,6 @@ import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContext.* import org.jetbrains.kotlin.resolve.BindingContext.*
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
@@ -56,6 +55,7 @@ import org.jetbrains.kotlin.resolve.calls.util.isSingleUnderscore
import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.indexOrMinusOne
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils.* import org.jetbrains.kotlin.types.TypeUtils.*
@@ -437,31 +437,31 @@ class ControlFlowInformationProvider private constructor(
val containingDeclarationDescriptor = variableDescriptor.containingDeclaration val containingDeclarationDescriptor = variableDescriptor.containingDeclaration
// Do not consider top-level properties // Do not consider top-level properties
if (containingDeclarationDescriptor is PackageFragmentDescriptor) return false if (containingDeclarationDescriptor is PackageFragmentDescriptor) return false
var parentDeclaration = getElementParentDeclaration(writeValueInstruction.element) var parentDeclaration = writeValueInstruction.element.getElementParentDeclaration()
loop@ while (true) { loop@ while (true) {
val context = trace.bindingContext val context = trace.bindingContext
val parentDescriptor = getDeclarationDescriptorIncludingConstructors(context, parentDeclaration) val parentDescriptor = parentDeclaration.getDeclarationDescriptorIncludingConstructors(context)
if (parentDescriptor == containingDeclarationDescriptor) { if (parentDescriptor == containingDeclarationDescriptor) {
return false return false
} }
when (parentDeclaration) { when (parentDeclaration) {
is KtObjectDeclaration, is KtClassInitializer -> { is KtObjectDeclaration, is KtClassInitializer -> {
// anonymous objects / initializers count here the same as its owner // anonymous objects / initializers count here the same as its owner
parentDeclaration = getElementParentDeclaration(parentDeclaration) parentDeclaration = parentDeclaration.getElementParentDeclaration()
} }
is KtDeclarationWithBody -> { is KtDeclarationWithBody -> {
// If it is captured write in lambda that is called in-place, then skip it (treat as parent) // If it is captured write in lambda that is called in-place, then skip it (treat as parent)
val maybeEnclosingLambdaExpr = parentDeclaration.parent val maybeEnclosingLambdaExpr = parentDeclaration.parent
if (maybeEnclosingLambdaExpr is KtLambdaExpression && trace[LAMBDA_INVOCATIONS, maybeEnclosingLambdaExpr] != null) { if (maybeEnclosingLambdaExpr is KtLambdaExpression && trace[LAMBDA_INVOCATIONS, maybeEnclosingLambdaExpr] != null) {
parentDeclaration = getElementParentDeclaration(parentDeclaration) parentDeclaration = parentDeclaration.getElementParentDeclaration()
continue@loop continue@loop
} }
if (parentDeclaration is KtFunction && parentDeclaration.isLocal) return true if (parentDeclaration is KtFunction && parentDeclaration.isLocal) return true
// miss non-local function or accessor just once // miss non-local function or accessor just once
parentDeclaration = getElementParentDeclaration(parentDeclaration) parentDeclaration = parentDeclaration.getElementParentDeclaration()
return getDeclarationDescriptorIncludingConstructors(context, parentDeclaration) != containingDeclarationDescriptor return parentDeclaration.getDeclarationDescriptorIncludingConstructors(context) != containingDeclarationDescriptor
} }
else -> { else -> {
return true return true
@@ -851,7 +851,7 @@ class ControlFlowInformationProvider private constructor(
if (descriptor is ParameterDescriptor) { if (descriptor is ParameterDescriptor) {
val containing = descriptor.containingDeclaration val containing = descriptor.containingDeclaration
if (containing is AnonymousFunctionDescriptor && containing.isSuspend) { if (containing is AnonymousFunctionDescriptor && containing.isSuspend) {
trace.record(SUSPEND_LAMBDA_PARAMETER_USED, containing to descriptor.index()) trace.record(SUSPEND_LAMBDA_PARAMETER_USED, containing to descriptor.indexOrMinusOne())
} }
} else if (descriptor is LocalVariableDescriptor) { } else if (descriptor is LocalVariableDescriptor) {
val containing = descriptor.containingDeclaration val containing = descriptor.containingDeclaration
@@ -1222,26 +1222,6 @@ class ControlFlowInformationProvider private constructor(
) : VariableContext(instruction, map) ) : VariableContext(instruction, map)
companion object { companion object {
// Should return KtDeclarationWithBody, KtClassOrObject, or KtClassInitializer
fun getElementParentDeclaration(element: KtElement) =
getParentOfType(element, KtDeclarationWithBody::class.java, KtClassOrObject::class.java, KtClassInitializer::class.java)
fun getDeclarationDescriptorIncludingConstructors(context: BindingContext, declaration: KtDeclaration?): DeclarationDescriptor? {
val descriptor = context.get(
DECLARATION_TO_DESCRIPTOR,
(declaration as? KtClassInitializer)?.containingDeclaration ?: declaration
)
return if (descriptor is ClassDescriptor && declaration is KtClassInitializer) {
// For a class primary constructor, we cannot directly get ConstructorDescriptor by KtClassInitializer,
// so we have to do additional conversion: KtClassInitializer -> KtClassOrObject -> ClassDescriptor -> ConstructorDescriptor
descriptor.unsubstitutedPrimaryConstructor
?: (descriptor as? ClassDescriptorWithResolutionScopes)?.scopeForInitializerResolution?.ownerDescriptor
} else {
descriptor
}
}
private fun isUsedAsResultOfLambda(usages: List<Instruction>): Boolean { private fun isUsedAsResultOfLambda(usages: List<Instruction>): Boolean {
for (usage in usages) { for (usage in usages) {
if (usage is ReturnValueInstruction) { if (usage is ReturnValueInstruction) {
@@ -1318,10 +1298,3 @@ class ControlFlowInformationProvider private constructor(
|| diagnosticFactory === UNUSED_CHANGED_VALUE || diagnosticFactory === UNUSED_CHANGED_VALUE
} }
} }
fun ParameterDescriptor.index(): Int =
when (this) {
is ReceiverParameterDescriptor -> -1
is ValueParameterDescriptor -> index
else -> error("expected either receiver or value parameter, but got: $this")
}
@@ -0,0 +1,23 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.cfg
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.psi.KtClassOrObject
interface LeakingThisDescriptor {
val classOrObject: KtClassOrObject
data class PropertyIsNull(val property: PropertyDescriptor, override val classOrObject: KtClassOrObject) : LeakingThisDescriptor
data class NonFinalClass(val klass: ClassDescriptor, override val classOrObject: KtClassOrObject) : LeakingThisDescriptor
data class NonFinalProperty(val property: PropertyDescriptor, override val classOrObject: KtClassOrObject) : LeakingThisDescriptor
data class NonFinalFunction(val function: FunctionDescriptor, override val classOrObject: KtClassOrObject) : LeakingThisDescriptor
}
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.cfg
import com.intellij.psi.util.PsiTreeUtil.getParentOfType
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContext.DECLARATION_TO_DESCRIPTOR
val KtElement.containingDeclarationForPseudocode: KtDeclaration?
get() = getParentOfType(this, KtDeclarationWithBody::class.java, KtClassOrObject::class.java, KtScript::class.java)
?: getNonStrictParentOfType<KtProperty>()
// Should return KtDeclarationWithBody, KtClassOrObject, or KtClassInitializer
fun KtElement.getElementParentDeclaration(): KtDeclaration? =
getParentOfType(this, KtDeclarationWithBody::class.java, KtClassOrObject::class.java, KtClassInitializer::class.java)
fun KtDeclaration?.getDeclarationDescriptorIncludingConstructors(context: BindingContext): DeclarationDescriptor? {
val descriptor = context.get(DECLARATION_TO_DESCRIPTOR, (this as? KtClassInitializer)?.containingDeclaration ?: this)
return if (descriptor is ClassDescriptor && this is KtClassInitializer) {
// For a class primary constructor, we cannot directly get ConstructorDescriptor by KtClassInitializer,
// so we have to do additional conversion: KtClassInitializer -> KtClassOrObject -> ClassDescriptor -> ConstructorDescriptor
descriptor.unsubstitutedPrimaryConstructor
?: (descriptor as? ClassDescriptorWithResolutionScopes)?.scopeForInitializerResolution?.ownerDescriptor
} else {
descriptor
}
}
@@ -16,9 +16,9 @@
package org.jetbrains.kotlin.cfg.pseudocode package org.jetbrains.kotlin.cfg.pseudocode
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.cfg.Label import org.jetbrains.kotlin.cfg.Label
import org.jetbrains.kotlin.cfg.containingDeclarationForPseudocode
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.* import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.*
import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.MagicKind.* import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.MagicKind.*
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.cfg.pseudocode.instructions.jumps.ThrowExceptionInst
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.parents import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.renderer.DescriptorRenderer
@@ -279,10 +278,6 @@ fun Pseudocode.getElementValuesRecursively(element: KtElement): List<PseudoValue
return results return results
} }
val KtElement.containingDeclarationForPseudocode: KtDeclaration?
get() = PsiTreeUtil.getParentOfType(this, KtDeclarationWithBody::class.java, KtClassOrObject::class.java, KtScript::class.java)
?: getNonStrictParentOfType<KtProperty>()
fun KtDeclaration.getContainingPseudocode(context: BindingContext): Pseudocode? { fun KtDeclaration.getContainingPseudocode(context: BindingContext): Pseudocode? {
val enclosingPseudocodeDeclaration = (this as? KtFunctionLiteral)?.let { val enclosingPseudocodeDeclaration = (this as? KtFunctionLiteral)?.let {
it.parents.firstOrNull { it is KtDeclaration && it !is KtFunctionLiteral } as? KtDeclaration it.parents.firstOrNull { it is KtDeclaration && it !is KtFunctionLiteral } as? KtDeclaration
@@ -5,7 +5,8 @@
package org.jetbrains.kotlin.resolve.calls.smartcasts package org.jetbrains.kotlin.resolve.calls.smartcasts
import org.jetbrains.kotlin.cfg.ControlFlowInformationProvider import org.jetbrains.kotlin.cfg.getDeclarationDescriptorIncludingConstructors
import org.jetbrains.kotlin.cfg.getElementParentDeclaration
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
@@ -102,10 +103,8 @@ fun hasNoWritersInClosures(
bindingContext: BindingContext bindingContext: BindingContext
): Boolean { ): Boolean {
return writers.none { (_, writerDeclaration) -> return writers.none { (_, writerDeclaration) ->
val writerDescriptor = writerDeclaration?.let { writerDeclaration != null &&
ControlFlowInformationProvider.getDeclarationDescriptorIncludingConstructors(bindingContext, it) variableContainingDeclaration != writerDeclaration.getDeclarationDescriptorIncludingConstructors(bindingContext)
}
writerDeclaration != null && variableContainingDeclaration != writerDescriptor
} }
} }
@@ -113,7 +112,7 @@ private fun isAccessedInsideClosureAfterAllWriters(
writers: Set<AssignedVariablesSearcher.Writer>, writers: Set<AssignedVariablesSearcher.Writer>,
accessElement: KtElement accessElement: KtElement
): Boolean { ): Boolean {
val parent = ControlFlowInformationProvider.getElementParentDeclaration(accessElement) ?: return false val parent = accessElement.getElementParentDeclaration() ?: return false
return writers.none { (assignment) -> !assignment.before(parent) } return writers.none { (assignment) -> !assignment.before(parent) }
} }
@@ -126,9 +125,7 @@ private fun isAccessedBeforeAllClosureWriters(
// All writers should be before access element, with the exception: // All writers should be before access element, with the exception:
// writer which is the same with declaration site does not count // writer which is the same with declaration site does not count
writers.mapNotNull { it.declaration }.forEach { writerDeclaration -> writers.mapNotNull { it.declaration }.forEach { writerDeclaration ->
val writerDescriptor = ControlFlowInformationProvider.getDeclarationDescriptorIncludingConstructors( val writerDescriptor = writerDeclaration.getDeclarationDescriptorIncludingConstructors(bindingContext)
bindingContext, writerDeclaration
)
// Access is after some writerDeclaration // Access is after some writerDeclaration
if (variableContainingDeclaration != writerDescriptor && !accessElement.before(writerDeclaration)) { if (variableContainingDeclaration != writerDescriptor && !accessElement.before(writerDeclaration)) {
return false return false
@@ -156,10 +153,9 @@ private fun isAccessedInsideClosure(
bindingContext: BindingContext, bindingContext: BindingContext,
accessElement: KtElement accessElement: KtElement
): Boolean { ): Boolean {
val parent = ControlFlowInformationProvider.getElementParentDeclaration(accessElement) val parent = accessElement.getElementParentDeclaration()
return if (parent != null) // Access is at the same declaration: not in closure, lower: in closure return if (parent != null) // Access is at the same declaration: not in closure, lower: in closure
ControlFlowInformationProvider.getDeclarationDescriptorIncludingConstructors(bindingContext, parent) != parent.getDeclarationDescriptorIncludingConstructors(bindingContext) != variableContainingDeclaration
variableContainingDeclaration
else else
false false
} }
@@ -5,10 +5,7 @@
package org.jetbrains.kotlin.resolve package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.types.DeferredType import org.jetbrains.kotlin.types.DeferredType
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.contains import org.jetbrains.kotlin.types.typeUtil.contains
@@ -28,10 +25,16 @@ fun FunctionDescriptor.isFunctionForExpectTypeFromCastFeature(): Boolean {
return true return true
} }
internal fun CallableMemberDescriptor.isEffectivelyFinal(ignoreEnumClassFinality: Boolean): Boolean = internal fun CallableMemberDescriptor.isEffectivelyFinal(ignoreEnumClassFinality: Boolean): Boolean =
modality == Modality.FINAL || modality == Modality.FINAL ||
containingDeclaration.let { parent -> containingDeclaration.let { parent ->
(ignoreEnumClassFinality || !DescriptorUtils.isEnumClass(parent)) && (ignoreEnumClassFinality || !DescriptorUtils.isEnumClass(parent)) &&
parent is ClassDescriptor && parent.modality == Modality.FINAL parent is ClassDescriptor && parent.modality == Modality.FINAL
} }
fun ParameterDescriptor.indexOrMinusOne(): Int =
when (this) {
is ReceiverParameterDescriptor -> -1
is ValueParameterDescriptor -> index
else -> error("expected either receiver or value parameter, but got: $this")
}
@@ -5,8 +5,8 @@
package org.jetbrains.kotlin.util package org.jetbrains.kotlin.util
import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.cfg.containingDeclarationForPseudocode
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
@@ -10,7 +10,7 @@ import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.impl.source.tree.LeafPsiElement import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.intellij.psi.util.parentOfType import com.intellij.psi.util.parentOfType
import com.intellij.psi.util.parentsOfType import com.intellij.psi.util.parentsOfType
import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode import org.jetbrains.kotlin.cfg.containingDeclarationForPseudocode
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
@@ -10,7 +10,7 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiManager import com.intellij.psi.PsiManager
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
import org.jetbrains.kotlin.asJava.toLightClass import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode import org.jetbrains.kotlin.cfg.containingDeclarationForPseudocode
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtVisitorVoid import org.jetbrains.kotlin.psi.KtVisitorVoid
import kotlin.system.measureNanoTime import kotlin.system.measureNanoTime
@@ -23,7 +23,7 @@ import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.search.searches.ReferencesSearch import com.intellij.psi.search.searches.ReferencesSearch
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
import org.jetbrains.kotlin.cfg.pseudocode.PseudocodeUtil import org.jetbrains.kotlin.cfg.pseudocode.PseudocodeUtil
import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode import org.jetbrains.kotlin.cfg.containingDeclarationForPseudocode
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionWithNext import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionWithNext
import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.AccessTarget import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.AccessTarget
@@ -21,7 +21,7 @@ import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.tree.IElementType import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode import org.jetbrains.kotlin.cfg.containingDeclarationForPseudocode
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.analysis.analyzeAsReplacement import org.jetbrains.kotlin.idea.analysis.analyzeAsReplacement
import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.KotlinBundle
@@ -10,7 +10,7 @@ import com.intellij.openapi.util.Ref
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
import org.jetbrains.kotlin.cfg.pseudocode.PseudocodeUtil import org.jetbrains.kotlin.cfg.pseudocode.PseudocodeUtil
import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode import org.jetbrains.kotlin.cfg.containingDeclarationForPseudocode
import org.jetbrains.kotlin.idea.analysis.analyzeAsReplacement import org.jetbrains.kotlin.idea.analysis.analyzeAsReplacement
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.result.* import org.jetbrains.kotlin.idea.intentions.loopToCallChain.result.*
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.idea.quickfix
import com.intellij.codeInsight.intention.IntentionAction import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.builtins.isFunctionType
import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode import org.jetbrains.kotlin.cfg.containingDeclarationForPseudocode
import org.jetbrains.kotlin.codegen.inline.isInlineOrInsideInline import org.jetbrains.kotlin.codegen.inline.isInlineOrInsideInline
import org.jetbrains.kotlin.descriptors.ValueDescriptor import org.jetbrains.kotlin.descriptors.ValueDescriptor
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
@@ -88,4 +88,4 @@ class AddSuspendModifierFix(
return AddSuspendModifierFix(variableTypeReference, declaration.name) return AddSuspendModifierFix(variableTypeReference, declaration.name)
} }
} }
} }
@@ -11,6 +11,7 @@ import com.intellij.psi.util.PsiTreeUtil
import com.intellij.refactoring.util.RefactoringUIUtil import com.intellij.refactoring.util.RefactoringUIUtil
import com.intellij.util.containers.MultiMap import com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.cfg.containingDeclarationForPseudocode
import org.jetbrains.kotlin.cfg.pseudocode.* import org.jetbrains.kotlin.cfg.pseudocode.*
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult
@@ -18,7 +18,7 @@ import com.intellij.util.Processor
import org.jetbrains.kotlin.asJava.namedUnwrappedElement import org.jetbrains.kotlin.asJava.namedUnwrappedElement
import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode import org.jetbrains.kotlin.cfg.containingDeclarationForPseudocode
import org.jetbrains.kotlin.cfg.pseudocode.getContainingPseudocode import org.jetbrains.kotlin.cfg.pseudocode.getContainingPseudocode
import org.jetbrains.kotlin.cfg.pseudocode.instructions.KtElementInstruction import org.jetbrains.kotlin.cfg.pseudocode.instructions.KtElementInstruction
import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.* import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.*