From 509ed69d28c705ad16a93df3ce4c14cefe5c5b03 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 5 Jul 2022 17:27:01 +0300 Subject: [PATCH] [K1] Get rid of CONSERVATIVE_SET_INCLUSION_SEMANTICS rewrite policy This policy didn't work in IDE, because trace in IDE always allow rewrites to slices ^KT-53072 Fixed --- .../cfg/ControlFlowInformationProviderImpl.kt | 12 ++++-------- .../kotlin/cfg/ControlFlowProcessor.kt | 6 +++--- .../kotlin/resolve/BindingContext.java | 5 ++--- .../bindingContextUtil/BindingContextUtils.kt | 9 +++++++-- .../kotlin/util/slicedMap/Slices.java | 18 ------------------ 5 files changed, 16 insertions(+), 34 deletions(-) diff --git a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt index 51afd2071a0..86cae2900e9 100644 --- a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt +++ b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt @@ -41,16 +41,12 @@ 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 +import org.jetbrains.kotlin.resolve.bindingContextUtil.* import org.jetbrains.kotlin.resolve.calls.checkers.findDestructuredVariable import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall import org.jetbrains.kotlin.resolve.calls.util.* import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver @@ -823,7 +819,7 @@ class ControlFlowInformationProviderImpl private constructor( val isUsedAsExpression = usages.isNotEmpty() val isUsedAsResultOfLambda = isUsedAsResultOfLambda(usages) for (element in pseudocode.getValueElements(value)) { - trace.record(USED_AS_EXPRESSION, element, isUsedAsExpression) + element.recordUsedAsExpression(trace, isUsedAsExpression) trace.record(USED_AS_RESULT_OF_LAMBDA, element, isUsedAsResultOfLambda) if (isUsedAsExpression) { when (element) { @@ -849,7 +845,7 @@ class ControlFlowInformationProviderImpl private constructor( } private fun KtExpression.recordUsedAsExpression() { - trace.record(USED_AS_EXPRESSION, this, true) + recordUsedAsExpression(trace, true) } private fun checkForSuspendLambdaAndMarkParameters(pseudocode: Pseudocode) { @@ -958,7 +954,7 @@ class ControlFlowInformationProviderImpl private constructor( private fun markAnnotationArguments(entry: KtAnnotationEntry) { for (argument in entry.valueArguments) { argument.getArgumentExpression()?.forEachDescendantOfType { - trace.record(USED_AS_EXPRESSION, it, true) + it.recordUsedAsExpression(trace, true) } } } diff --git a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt index 590f6490536..95b29fc9de2 100644 --- a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt +++ b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt @@ -45,10 +45,10 @@ import org.jetbrains.kotlin.lexer.KtTokens.* import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.BindingContext.USED_AS_EXPRESSION import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils import org.jetbrains.kotlin.resolve.bindingContextUtil.getEnclosingFunctionDescriptor +import org.jetbrains.kotlin.resolve.bindingContextUtil.recordUsedAsExpression import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall @@ -352,7 +352,7 @@ class ControlFlowProcessor( builder.bindLabel(afterElvis) mergeValues(listOfNotNull(left, right), expression) if (right != null && languageVersionSettings.supportsFeature(LanguageFeature.ProhibitNonExhaustiveIfInRhsOfElvis)) { - trace.record(USED_AS_EXPRESSION, right, true) + right.recordUsedAsExpression(trace, true) } } else { if (!generateCall(expression)) { @@ -1438,7 +1438,7 @@ class ControlFlowProcessor( if (declaration is KtAnonymousInitializer) { generateInstructions(declaration) if (hasResultField && declaration == lastInitializer) { - trace.record(USED_AS_EXPRESSION, resultExpression, true) + resultExpression?.recordUsedAsExpression(trace, true) } } else if (declaration is KtProperty || declaration is KtDestructuringDeclaration) { generateInstructions(declaration) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java index cef2ea4ed4a..11fcc0ad02d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java @@ -52,7 +52,6 @@ import java.util.Collections; import static org.jetbrains.kotlin.util.slicedMap.RewritePolicy.DO_NOTHING; import static org.jetbrains.kotlin.util.slicedMap.Slices.COMPILE_TIME_VALUE_REWRITE_POLICY; -import static org.jetbrains.kotlin.util.slicedMap.Slices.CONSERVATIVE_SET_INCLUSION_SEMANTICS; public interface BindingContext { BindingContext EMPTY = new BindingContext() { @@ -184,8 +183,8 @@ public interface BindingContext { */ WritableSlice PROCESSED = Slices.createSimpleSlice(); // Please do not use this slice (USED_AS_EXPRESSION) directly, - // use extension element.isUsedAsExpression() instead - WritableSlice USED_AS_EXPRESSION = new BasicWritableSlice<>(CONSERVATIVE_SET_INCLUSION_SEMANTICS); + // use extension element.isUsedAsExpression() for read and element.recordUsedAsExpression() for write + WritableSlice USED_AS_EXPRESSION = new BasicWritableSlice<>(DO_NOTHING); WritableSlice USED_AS_RESULT_OF_LAMBDA = Slices.createSimpleSetSlice(); WritableSlice CAPTURED_IN_CLOSURE = new BasicWritableSlice<>(DO_NOTHING); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/bindingContextUtil/BindingContextUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/bindingContextUtil/BindingContextUtils.kt index b3e15cbbbaf..d5c3404e009 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/bindingContextUtil/BindingContextUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/bindingContextUtil/BindingContextUtils.kt @@ -56,9 +56,14 @@ fun KtReturnExpression.getTargetFunction(context: BindingContext): KtCallableDec return getTargetFunctionDescriptor(context)?.let { DescriptorToSourceUtils.descriptorToDeclaration(it) as? KtCallableDeclaration } } -fun KtExpression.isUsedAsExpression(context: BindingContext): Boolean = +fun KtElement.isUsedAsExpression(context: BindingContext): Boolean = context[USED_AS_EXPRESSION, this] ?: false +fun KtElement.recordUsedAsExpression(trace: BindingTrace, value: Boolean) { + if (isUsedAsExpression(trace.bindingContext)) return + trace.record(USED_AS_EXPRESSION, this, value) +} + fun KtExpression.isUsedAsResultOfLambda(context: BindingContext): Boolean = context[USED_AS_RESULT_OF_LAMBDA, this]!! fun KtExpression.isUsedAsStatement(context: BindingContext): Boolean = !isUsedAsExpression(context) @@ -157,4 +162,4 @@ fun getEnclosingFunctionDescriptor(context: BindingContext, element: KtElement): } else { if (descriptor is ClassDescriptor) descriptor.unsubstitutedPrimaryConstructor else null } -} \ No newline at end of file +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/util/slicedMap/Slices.java b/compiler/frontend/src/org/jetbrains/kotlin/util/slicedMap/Slices.java index 4b7d8b99120..494434aef08 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/util/slicedMap/Slices.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/util/slicedMap/Slices.java @@ -80,24 +80,6 @@ public class Slices { } }; - // For Boolean-valued slices modelling set-membership, this policy - // implements constructing a set by element-wise inclusion, conservatively: - // allow rewriting false->true but not true->false. - // - // Used in growing the set of `USED_AS_EXPRESSION` in CFG analysis. - public static final RewritePolicy CONSERVATIVE_SET_INCLUSION_SEMANTICS = new RewritePolicy() { - @Override - public boolean rewriteProcessingNeeded(K key) { - return true; - } - - @Override - public boolean processRewrite(WritableSlice slice, K key, V oldValue, V newValue) { - assert (newValue instanceof Boolean); - return (Boolean)newValue; - } - }; - private Slices() { }