diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt index 618cedcc757..504463c622a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.BindingContext.* +import org.jetbrains.kotlin.resolve.bindingContextUtil.getEnclosingDescriptor import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsResultOfLambda import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement @@ -471,7 +472,7 @@ class ControlFlowInformationProvider private constructor( trace.get(BACKING_FIELD_REQUIRED, it) } ?: true if (variableDescriptor is PropertyDescriptor && variableDescriptor.isVar) { - val descriptor = BindingContextUtils.getEnclosingDescriptor(trace.bindingContext, expression) + val descriptor = getEnclosingDescriptor(trace.bindingContext, expression) val setterDescriptor = variableDescriptor.setter val receiverValue = expression.getResolvedCall(trace.bindingContext)?.getDispatchReceiverWithSmartCast() diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt index 2681c251a26..84e9487bdf2 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt @@ -50,6 +50,7 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContextUtils import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils +import org.jetbrains.kotlin.resolve.bindingContextUtil.getEnclosingFunctionDescriptor import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall @@ -916,8 +917,8 @@ class ControlFlowProcessor( private fun jumpDoesNotCrossFunctionBoundary(jumpExpression: KtExpressionWithLabel, jumpTarget: KtLoopExpression): Boolean { val bindingContext = trace.bindingContext - val labelExprEnclosingFunc = BindingContextUtils.getEnclosingFunctionDescriptor(bindingContext, jumpExpression) - val labelTargetEnclosingFunc = BindingContextUtils.getEnclosingFunctionDescriptor(bindingContext, jumpTarget) + val labelExprEnclosingFunc = getEnclosingFunctionDescriptor(bindingContext, jumpExpression) + val labelTargetEnclosingFunc = getEnclosingFunctionDescriptor(bindingContext, jumpTarget) return if (labelExprEnclosingFunc !== labelTargetEnclosingFunc) { // Check to report only once if (builder.getLoopExitPoint(jumpTarget) != null || diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.java index 214bfaf8c42..e95d7391392 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.java @@ -8,12 +8,12 @@ package org.jetbrains.kotlin.resolve; import com.google.common.collect.Lists; import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; -import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.diagnostics.Diagnostic; import org.jetbrains.kotlin.psi.*; +import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt; import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall; @@ -111,31 +111,6 @@ public class BindingContextUtils { return value; } - @NotNull - public static DeclarationDescriptor getEnclosingDescriptor(@NotNull BindingContext context, @NotNull KtElement element) { - KtNamedDeclaration declaration = PsiTreeUtil.getParentOfType(element, KtNamedDeclaration.class); - if (declaration instanceof KtFunctionLiteral) { - return getEnclosingDescriptor(context, declaration); - } - DeclarationDescriptor descriptor = context.get(DECLARATION_TO_DESCRIPTOR, declaration); - assert descriptor != null : "No descriptor for named declaration: " + declaration.getText() + "\n(of type " + declaration.getClass() + ")"; - return descriptor; - } - - @Nullable - public static FunctionDescriptor getEnclosingFunctionDescriptor(@NotNull BindingContext context, @NotNull KtElement element) { - KtElement functionOrClass = PsiTreeUtil.getParentOfType(element, KtFunction.class, KtClassOrObject.class); - DeclarationDescriptor descriptor = context.get(DECLARATION_TO_DESCRIPTOR, functionOrClass); - if (functionOrClass instanceof KtFunction) { - if (descriptor instanceof FunctionDescriptor) return (FunctionDescriptor) descriptor; - return null; - } - else { - if (descriptor instanceof ClassDescriptor) return ((ClassDescriptor) descriptor).getUnsubstitutedPrimaryConstructor(); - return null; - } - } - public static void reportAmbiguousLabel( @NotNull BindingTrace trace, @NotNull KtSimpleNameExpression targetLabel, diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.kt index c869a36dbb7..0bf5c04988e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.kt @@ -17,6 +17,8 @@ package org.jetbrains.kotlin.resolve.bindingContextUtil import com.intellij.psi.PsiElement +import com.intellij.psi.util.PsiTreeUtil +import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor @@ -114,4 +116,38 @@ fun KtTypeElement.getAbbreviatedTypeOrType(context: BindingContext): KotlinType? } else -> null } +} + +fun KtElement.getParentOfTypeCodeFragmentAware(vararg parentClasses: Class): T? { + PsiTreeUtil.getParentOfType(this, *parentClasses)?.let { return it } + + val containingFile = this.containingFile + if (containingFile is KtCodeFragment) { + val context = containingFile.context + if (context != null) { + return PsiTreeUtil.getParentOfType(context, *parentClasses) + } + } + + return null +} + +fun getEnclosingDescriptor(context: BindingContext, element: KtElement): DeclarationDescriptor { + val declaration = element.getParentOfTypeCodeFragmentAware(KtNamedDeclaration::class.java) + return if (declaration is KtFunctionLiteral) { + getEnclosingDescriptor(context, declaration) + } else { + context.get(DECLARATION_TO_DESCRIPTOR, declaration) + ?: error("No descriptor for named declaration: " + declaration?.text + "\n(of type " + declaration?.javaClass + ")") + } +} + +fun getEnclosingFunctionDescriptor(context: BindingContext, element: KtElement): FunctionDescriptor? { + val functionOrClass = element.getParentOfTypeCodeFragmentAware(KtFunction::class.java, KtClassOrObject::class.java) + val descriptor = context.get(DECLARATION_TO_DESCRIPTOR, functionOrClass) + return if (functionOrClass is KtFunction) { + if (descriptor is FunctionDescriptor) descriptor else null + } else { + if (descriptor is ClassDescriptor) descriptor.unsubstitutedPrimaryConstructor else null + } } \ No newline at end of file