Ease field initialization check
Since there is already VAL_REASSIGNMENT diagnostics, we can safely only for direct assignments. #KT-40893 Fixed
This commit is contained in:
Generated
+5
@@ -5156,6 +5156,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt");
|
runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("listAppend.kt")
|
||||||
|
public void testListAppend() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/contracts/listAppend.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("valInWhen.kt")
|
@TestMetadata("valInWhen.kt")
|
||||||
public void testValInWhen() throws Exception {
|
public void testValInWhen() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/contracts/valInWhen.kt");
|
runTest("compiler/testData/codegen/box/contracts/valInWhen.kt");
|
||||||
|
|||||||
+7
-2
@@ -14,8 +14,8 @@ import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.CAPTURED_VAL_INITIALIZATION
|
import org.jetbrains.kotlin.diagnostics.Errors.CAPTURED_VAL_INITIALIZATION
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext.CAPTURED_IN_CLOSURE
|
import org.jetbrains.kotlin.resolve.BindingContext.CAPTURED_IN_CLOSURE
|
||||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
@@ -58,7 +58,7 @@ class CapturingInClosureChecker : CallChecker {
|
|||||||
nameElement: PsiElement
|
nameElement: PsiElement
|
||||||
) {
|
) {
|
||||||
if (variable !is PropertyDescriptor || scopeContainer !is AnonymousFunctionDescriptor || variable.isVar) return
|
if (variable !is PropertyDescriptor || scopeContainer !is AnonymousFunctionDescriptor || variable.isVar) return
|
||||||
if ((nameElement as KtExpression).getAssignmentByLHS() == null) return
|
if (!isLhsOfAssignment(nameElement as KtExpression)) return
|
||||||
val scopeDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(scopeContainer) as? KtFunction ?: return
|
val scopeDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(scopeContainer) as? KtFunction ?: return
|
||||||
if (scopeContainer.containingDeclaration !is ConstructorDescriptor) return
|
if (scopeContainer.containingDeclaration !is ConstructorDescriptor) return
|
||||||
if (!isExactlyOnceContract(trace.bindingContext, scopeDeclaration)) return
|
if (!isExactlyOnceContract(trace.bindingContext, scopeDeclaration)) return
|
||||||
@@ -70,6 +70,11 @@ class CapturingInClosureChecker : CallChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isLhsOfAssignment(nameElement: KtExpression): Boolean {
|
||||||
|
val parent = nameElement.parent as? KtBinaryExpression ?: return false
|
||||||
|
return parent.operationToken == KtTokens.EQ && parent.left == nameElement
|
||||||
|
}
|
||||||
|
|
||||||
private fun isCapturedVariable(variableParent: DeclarationDescriptor, scopeContainer: DeclarationDescriptor): Boolean {
|
private fun isCapturedVariable(variableParent: DeclarationDescriptor, scopeContainer: DeclarationDescriptor): Boolean {
|
||||||
if (variableParent !is FunctionDescriptor || scopeContainer == variableParent) return false
|
if (variableParent !is FunctionDescriptor || scopeContainer == variableParent) return false
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
|
||||||
|
// IGNORE_BACKEND: NATIVE
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// KJS_WITH_FULL_RUNTIME
|
||||||
|
|
||||||
|
import kotlin.contracts.*
|
||||||
|
|
||||||
|
class A {
|
||||||
|
val value = arrayListOf("O")
|
||||||
|
|
||||||
|
init {
|
||||||
|
foo {
|
||||||
|
value += "K"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(block: () -> Unit) {
|
||||||
|
contract {
|
||||||
|
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||||
|
}
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a = A()
|
||||||
|
return if (a.value == listOf("O", "K")) "OK" else "FAIL"
|
||||||
|
}
|
||||||
+3
-3
@@ -71,13 +71,13 @@ class Test1 {
|
|||||||
<!VAL_REASSIGNMENT!>a<!> += "allowed"
|
<!VAL_REASSIGNMENT!>a<!> += "allowed"
|
||||||
}
|
}
|
||||||
crossinlineMe {
|
crossinlineMe {
|
||||||
<!CAPTURED_VAL_INITIALIZATION, VAL_REASSIGNMENT!>b<!> += "not allowed"
|
<!VAL_REASSIGNMENT!>b<!> += "not allowed"
|
||||||
}
|
}
|
||||||
noinlineMe {
|
noinlineMe {
|
||||||
<!CAPTURED_VAL_INITIALIZATION, VAL_REASSIGNMENT!>c<!> += "not allowed"
|
<!VAL_REASSIGNMENT!>c<!> += "not allowed"
|
||||||
}
|
}
|
||||||
notinline {
|
notinline {
|
||||||
<!CAPTURED_VAL_INITIALIZATION, VAL_REASSIGNMENT!>d<!> += "not allowed"
|
<!VAL_REASSIGNMENT!>d<!> += "not allowed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -5191,6 +5191,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt");
|
runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("listAppend.kt")
|
||||||
|
public void testListAppend() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/contracts/listAppend.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("valInWhen.kt")
|
@TestMetadata("valInWhen.kt")
|
||||||
public void testValInWhen() throws Exception {
|
public void testValInWhen() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/contracts/valInWhen.kt");
|
runTest("compiler/testData/codegen/box/contracts/valInWhen.kt");
|
||||||
|
|||||||
+5
@@ -5191,6 +5191,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt");
|
runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("listAppend.kt")
|
||||||
|
public void testListAppend() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/contracts/listAppend.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("valInWhen.kt")
|
@TestMetadata("valInWhen.kt")
|
||||||
public void testValInWhen() throws Exception {
|
public void testValInWhen() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/contracts/valInWhen.kt");
|
runTest("compiler/testData/codegen/box/contracts/valInWhen.kt");
|
||||||
|
|||||||
+5
@@ -5156,6 +5156,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt");
|
runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("listAppend.kt")
|
||||||
|
public void testListAppend() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/contracts/listAppend.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("valInWhen.kt")
|
@TestMetadata("valInWhen.kt")
|
||||||
public void testValInWhen() throws Exception {
|
public void testValInWhen() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/contracts/valInWhen.kt");
|
runTest("compiler/testData/codegen/box/contracts/valInWhen.kt");
|
||||||
|
|||||||
Generated
+5
@@ -4191,6 +4191,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
|||||||
runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt");
|
runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("listAppend.kt")
|
||||||
|
public void testListAppend() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/contracts/listAppend.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("valInWhen.kt")
|
@TestMetadata("valInWhen.kt")
|
||||||
public void testValInWhen() throws Exception {
|
public void testValInWhen() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/contracts/valInWhen.kt");
|
runTest("compiler/testData/codegen/box/contracts/valInWhen.kt");
|
||||||
|
|||||||
Generated
+5
@@ -4191,6 +4191,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt");
|
runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("listAppend.kt")
|
||||||
|
public void testListAppend() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/contracts/listAppend.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("valInWhen.kt")
|
@TestMetadata("valInWhen.kt")
|
||||||
public void testValInWhen() throws Exception {
|
public void testValInWhen() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/contracts/valInWhen.kt");
|
runTest("compiler/testData/codegen/box/contracts/valInWhen.kt");
|
||||||
|
|||||||
+5
@@ -4191,6 +4191,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt");
|
runTest("compiler/testData/codegen/box/contracts/lambdaParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("listAppend.kt")
|
||||||
|
public void testListAppend() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/contracts/listAppend.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("valInWhen.kt")
|
@TestMetadata("valInWhen.kt")
|
||||||
public void testValInWhen() throws Exception {
|
public void testValInWhen() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/contracts/valInWhen.kt");
|
runTest("compiler/testData/codegen/box/contracts/valInWhen.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user