[FIR] Report VAL_REASSIGNMENT on assign to non-local vals
In this commit reporting on member properties in init section of class is not supported (see KT-55528) ^KT-55493 Fixed
This commit is contained in:
committed by
Space Team
parent
e87a064cdd
commit
02e327277e
+12
@@ -1086,6 +1086,18 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
|
||||
public void testInitializationInTry() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfa/initializationInTry.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reassignOfNonLocalProperty_initializedProperties.kt")
|
||||
public void testReassignOfNonLocalProperty_initializedProperties() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfa/reassignOfNonLocalProperty_initializedProperties.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reassignOfNonMemberProperty_lateInitialization.kt")
|
||||
public void testReassignOfNonMemberProperty_lateInitialization() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfa/reassignOfNonMemberProperty_lateInitialization.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+10
@@ -940,6 +940,16 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
||||
public void testInitializationInTry() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfa/initializationInTry.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("reassignOfNonLocalProperty_initializedProperties.kt")
|
||||
public void testReassignOfNonLocalProperty_initializedProperties() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfa/reassignOfNonLocalProperty_initializedProperties.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("reassignOfNonMemberProperty_lateInitialization.kt")
|
||||
public void testReassignOfNonMemberProperty_lateInitialization() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfa/reassignOfNonMemberProperty_lateInitialization.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/cfg")
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
FILE: reassignOfNonLocalProperty_initializedProperties.kt
|
||||
public final val z: R|kotlin/String| = String(ok)
|
||||
public get(): R|kotlin/String|
|
||||
public final val R|Some|.y: R|kotlin/String|
|
||||
public get(): R|kotlin/String| {
|
||||
^ String(ok)
|
||||
}
|
||||
public final class Some : R|kotlin/Any| {
|
||||
public constructor(): R|Some| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final val x: R|kotlin/String| = String(ok)
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
init {
|
||||
this@R|/Some|.R|/Some.x| = String(error)
|
||||
this@R|/Some|.R|/y| = String(error)
|
||||
R|/z| = String(error)
|
||||
}
|
||||
|
||||
public final val a: R|kotlin/String| = this@R|/Some|.R|kotlin/run|<R|Some|, R|kotlin/String|>(<L> = run@fun R|Some|.<anonymous>(): R|kotlin/String| <inline=Inline, kind=EXACTLY_ONCE> {
|
||||
this@R|special/anonymous|.R|/Some.x| = String(error)
|
||||
this@R|special/anonymous|.R|/y| = String(error)
|
||||
R|/z| = String(error)
|
||||
^ String(hello)
|
||||
}
|
||||
)
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
public final fun test_1(): R|kotlin/Unit| {
|
||||
this@R|/Some|.R|/Some.x| = String(error)
|
||||
this@R|/Some|.R|/y| = String(error)
|
||||
R|/z| = String(error)
|
||||
}
|
||||
|
||||
}
|
||||
public final fun R|Some|.test_2(): R|kotlin/Unit| {
|
||||
this@R|/test_2|.R|/Some.x| = String(error)
|
||||
this@R|/test_2|.R|/y| = String(error)
|
||||
R|/z| = String(error)
|
||||
}
|
||||
public final fun test_3(some: R|Some|): R|kotlin/Unit| {
|
||||
R|<local>/some|.R|/Some.x| = String(error)
|
||||
R|<local>/some|.R|/y| = String(error)
|
||||
R|/z| = String(error)
|
||||
}
|
||||
compiler/fir/analysis-tests/testData/resolve/cfa/reassignOfNonLocalProperty_initializedProperties.kt
Vendored
+42
@@ -0,0 +1,42 @@
|
||||
// ISSUE: KT-55493
|
||||
// WITH_STDLIB
|
||||
|
||||
val z: String = "ok"
|
||||
|
||||
val Some.y: String
|
||||
get() = "ok"
|
||||
|
||||
class Some {
|
||||
val x: String = "ok"
|
||||
|
||||
init {
|
||||
<!VAL_REASSIGNMENT!>x<!> = "error"
|
||||
<!VAL_REASSIGNMENT!>y<!> = "error"
|
||||
<!VAL_REASSIGNMENT!>z<!> = "error"
|
||||
}
|
||||
|
||||
val a: String = run {
|
||||
<!VAL_REASSIGNMENT!>x<!> = "error"
|
||||
<!VAL_REASSIGNMENT!>y<!> = "error"
|
||||
<!VAL_REASSIGNMENT!>z<!> = "error"
|
||||
"hello"
|
||||
}
|
||||
|
||||
fun test_1() {
|
||||
<!VAL_REASSIGNMENT!>x<!> = "error"
|
||||
<!VAL_REASSIGNMENT!>y<!> = "error"
|
||||
<!VAL_REASSIGNMENT!>z<!> = "error"
|
||||
}
|
||||
}
|
||||
|
||||
fun Some.test_2() {
|
||||
<!VAL_REASSIGNMENT!>x<!> = "error"
|
||||
<!VAL_REASSIGNMENT!>y<!> = "error"
|
||||
<!VAL_REASSIGNMENT!>z<!> = "error"
|
||||
}
|
||||
|
||||
fun test_3(some: Some) {
|
||||
some.<!VAL_REASSIGNMENT!>x<!> = "error"
|
||||
some.<!VAL_REASSIGNMENT!>y<!> = "error"
|
||||
<!VAL_REASSIGNMENT!>z<!> = "error"
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
FILE: reassignOfNonMemberProperty_lateInitialization.kt
|
||||
public final val R|Some|.z: R|kotlin/String|
|
||||
public get(): R|kotlin/String| {
|
||||
^ String(ok)
|
||||
}
|
||||
public final class Some : R|kotlin/Any| {
|
||||
public constructor(): R|Some| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final val x: R|kotlin/String|
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
public final val y: R|kotlin/String|
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
init {
|
||||
this@R|/Some|.R|/Some.x| = String(ok)
|
||||
this@R|/Some|.R|/Some.x| = String(error)
|
||||
this@R|/Some|.R|/z| = String(error)
|
||||
}
|
||||
|
||||
public final val a: R|kotlin/String| = this@R|/Some|.R|kotlin/run|<R|Some|, R|kotlin/String|>(<L> = run@fun R|Some|.<anonymous>(): R|kotlin/String| <inline=Inline, kind=EXACTLY_ONCE> {
|
||||
this@R|special/anonymous|.R|/Some.x| = String(error)
|
||||
this@R|special/anonymous|.R|/Some.y| = String(ok)
|
||||
this@R|special/anonymous|.R|/Some.y| = String(error)
|
||||
this@R|special/anonymous|.R|/z| = String(error)
|
||||
^ String(hello)
|
||||
}
|
||||
)
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
init {
|
||||
this@R|/Some|.R|/Some.x| = String(error)
|
||||
this@R|/Some|.R|/Some.y| = String(error)
|
||||
this@R|/Some|.R|/z| = String(error)
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+31
@@ -0,0 +1,31 @@
|
||||
// ISSUE: KT-55493
|
||||
// WITH_STDLIB
|
||||
|
||||
val Some.z: String
|
||||
get() = "ok"
|
||||
|
||||
class Some {
|
||||
val x: String
|
||||
val y: String
|
||||
|
||||
init {
|
||||
x = "ok"
|
||||
x = "error"
|
||||
<!VAL_REASSIGNMENT!>z<!> = "error"
|
||||
}
|
||||
|
||||
val a: String = run {
|
||||
x = "error"
|
||||
y = "ok"
|
||||
y = "error"
|
||||
<!VAL_REASSIGNMENT!>z<!> = "error"
|
||||
"hello"
|
||||
}
|
||||
|
||||
init {
|
||||
x = "error"
|
||||
y = "error"
|
||||
<!VAL_REASSIGNMENT!>z<!> = "error"
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ fun main(d1: D1, d2: D2, d3: D3) {
|
||||
d2.bar(1, "").checkType { _<String>() }
|
||||
|
||||
d3.x.checkType { _<String>() }
|
||||
d3.x = ""
|
||||
d3.<!VAL_REASSIGNMENT!>x<!> = ""
|
||||
d3.foo().checkType { _<String?>() }
|
||||
d3.bar(1, "").checkType { _<String?>() }
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ class B(p0: String) {
|
||||
p3 = p1
|
||||
}
|
||||
init {
|
||||
p1 = <!ASSIGNMENT_TYPE_MISMATCH!>p0.length<!>
|
||||
<!VAL_REASSIGNMENT!>p1<!> = <!ASSIGNMENT_TYPE_MISMATCH!>p0.length<!>
|
||||
p3 = ""
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -1086,6 +1086,18 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
|
||||
public void testInitializationInTry() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfa/initializationInTry.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reassignOfNonLocalProperty_initializedProperties.kt")
|
||||
public void testReassignOfNonLocalProperty_initializedProperties() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfa/reassignOfNonLocalProperty_initializedProperties.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reassignOfNonMemberProperty_lateInitialization.kt")
|
||||
public void testReassignOfNonMemberProperty_lateInitialization() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfa/reassignOfNonMemberProperty_lateInitialization.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+12
@@ -1086,6 +1086,18 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
||||
public void testInitializationInTry() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfa/initializationInTry.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reassignOfNonLocalProperty_initializedProperties.kt")
|
||||
public void testReassignOfNonLocalProperty_initializedProperties() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfa/reassignOfNonLocalProperty_initializedProperties.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reassignOfNonMemberProperty_lateInitialization.kt")
|
||||
public void testReassignOfNonMemberProperty_lateInitialization() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfa/reassignOfNonMemberProperty_lateInitialization.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ object FirPropertyInitializationAnalyzer : AbstractFirPropertyInitializationChec
|
||||
} else {
|
||||
reporter.reportOn(node.fir.lValue.source, FirErrors.CAPTURED_MEMBER_VAL_INITIALIZATION, symbol, context)
|
||||
}
|
||||
} else if (symbol is FirSyntheticPropertySymbol || data.getValue(node).values.any { it[symbol]?.canBeRevisited() == true }) {
|
||||
} else if (data.getValue(node).values.any { it[symbol]?.canBeRevisited() == true }) {
|
||||
reporter.reportOn(node.fir.lValue.source, FirErrors.VAL_REASSIGNMENT, symbol, context)
|
||||
}
|
||||
}
|
||||
|
||||
-4
@@ -57,10 +57,6 @@ class LocalPropertyAndCapturedWriteCollector private constructor() : ControlFlow
|
||||
|
||||
override fun visitVariableAssignmentNode(node: VariableAssignmentNode) {
|
||||
val symbol = node.fir.calleeReference.toResolvedPropertySymbol() ?: return
|
||||
if (symbol is FirSyntheticPropertySymbol) {
|
||||
symbols[symbol] = true
|
||||
return
|
||||
}
|
||||
|
||||
// Check if this variable assignment is inside a lambda or a local function.
|
||||
if (lambdaOrLocalFunctionStack.isEmpty()) return
|
||||
|
||||
+48
@@ -12,7 +12,12 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousInitializer
|
||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.hasBackingField
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||
import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
||||
@@ -20,10 +25,15 @@ import org.jetbrains.kotlin.fir.originalForSubstitutionOverride
|
||||
import org.jetbrains.kotlin.fir.references.FirBackingFieldReference
|
||||
import org.jetbrains.kotlin.fir.references.FirThisReference
|
||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.references.toResolvedPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.references.toResolvedValueParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.ExpressionReceiverValue
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeSimpleKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.toSymbol
|
||||
import org.jetbrains.kotlin.fir.visibilityChecker
|
||||
|
||||
object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker() {
|
||||
@@ -32,6 +42,7 @@ object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker()
|
||||
checkValReassignmentViaBackingField(expression, context, reporter)
|
||||
checkValReassignmentOnValueParameter(expression, context, reporter)
|
||||
checkAssignmentToThis(expression, context, reporter)
|
||||
checkValReassignmentOfNonLocalProperty(expression, context, reporter)
|
||||
}
|
||||
|
||||
private fun checkInvisibleSetter(
|
||||
@@ -114,4 +125,41 @@ object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker()
|
||||
reporter.reportOn(expression.lValue.source, FirErrors.VARIABLE_EXPECTED, context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkValReassignmentOfNonLocalProperty(
|
||||
expression: FirVariableAssignment,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter
|
||||
) {
|
||||
val property = expression.lValue.toResolvedPropertySymbol() ?: return
|
||||
if (property.isLocal || property.isVar) return
|
||||
val assignIsIllegal = when (val dispatchReceiverType = property.dispatchReceiverType) {
|
||||
null -> true
|
||||
else -> when {
|
||||
property is FirSyntheticPropertySymbol -> true
|
||||
property.hasDelegate || !property.hasBackingField -> true
|
||||
property.hasInitializer -> true
|
||||
else -> !isInsideInitializationOfClass(dispatchReceiverType, context)
|
||||
}
|
||||
}
|
||||
if (assignIsIllegal) {
|
||||
reporter.reportOn(expression.lValue.source, FirErrors.VAL_REASSIGNMENT, property, context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isInsideInitializationOfClass(classType: ConeSimpleKotlinType, context: CheckerContext): Boolean {
|
||||
val session = context.session
|
||||
val classSymbol = classType.toSymbol(session) ?: return false
|
||||
for (containingDeclaration in context.containingDeclarations) {
|
||||
val containingClassSymbol = when (containingDeclaration) {
|
||||
is FirProperty -> containingDeclaration.containingClassLookupTag()?.toSymbol(session)
|
||||
is FirAnonymousInitializer -> containingDeclaration.dispatchReceiverType?.toSymbol(session)
|
||||
is FirConstructor -> containingDeclaration.containingClassLookupTag()?.toSymbol(session)
|
||||
else -> null
|
||||
} ?: continue
|
||||
|
||||
if (containingClassSymbol == classSymbol) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// IGNORE_BACKEND: JS, NATIVE
|
||||
// IGNORE_BACKEND_K2: ANY
|
||||
// FIR_STATUS: KT-35565
|
||||
// java.lang.AssertionError
|
||||
// at org.jetbrains.kotlin.js.translate.context.TranslationContext.getDispatchReceiver(TranslationContext.java:590)
|
||||
// at org.jetbrains.kotlin.js.translate.utils.TranslationUtils.backingFieldReference(TranslationUtils.java:237)
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND_K2: ANY
|
||||
// FIR_STATUS: KT-35565
|
||||
|
||||
// This test should become irrelevant after KT-35565 is fixed.
|
||||
|
||||
|
||||
@@ -11,14 +11,14 @@ class C() : B() {
|
||||
this.x = 34
|
||||
this.b = 123
|
||||
super.b = 23
|
||||
this.c = 34
|
||||
super.c = 3535 //repeat for 'c'
|
||||
this.<!VAL_REASSIGNMENT!>c<!> = 34
|
||||
super.<!VAL_REASSIGNMENT!>c<!> = 3535 //repeat for 'c'
|
||||
|
||||
<!VARIABLE_EXPECTED!>getInt()<!> = 12
|
||||
}
|
||||
|
||||
fun foo1(c: C) {
|
||||
super.c = 34
|
||||
super.<!VAL_REASSIGNMENT!>c<!> = 34
|
||||
}
|
||||
|
||||
fun bar(c: C) {
|
||||
|
||||
Vendored
+15
-15
@@ -116,8 +116,8 @@ class AnonymousInitializers(var a: String, val b: String) {
|
||||
a = "30"
|
||||
a = "s"
|
||||
|
||||
b = "3"
|
||||
b = "tt" //repeat for b
|
||||
<!VAL_REASSIGNMENT!>b<!> = "3"
|
||||
<!VAL_REASSIGNMENT!>b<!> = "tt" //repeat for b
|
||||
}
|
||||
|
||||
val i: Int
|
||||
@@ -127,7 +127,7 @@ class AnonymousInitializers(var a: String, val b: String) {
|
||||
|
||||
init {
|
||||
x = 11
|
||||
z = 10
|
||||
<!VAL_REASSIGNMENT!>z<!> = 10
|
||||
}
|
||||
|
||||
val j: Int
|
||||
@@ -135,7 +135,7 @@ class AnonymousInitializers(var a: String, val b: String) {
|
||||
|
||||
init {
|
||||
i = 13
|
||||
j = 34
|
||||
<!VAL_REASSIGNMENT!>j<!> = 34
|
||||
}
|
||||
|
||||
val k: String
|
||||
@@ -228,13 +228,13 @@ class Outer() {
|
||||
|
||||
inner class Inner() {
|
||||
init {
|
||||
a++
|
||||
<!VAL_REASSIGNMENT!>a<!>++
|
||||
b++
|
||||
}
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
a++
|
||||
<!VAL_REASSIGNMENT!>a<!>++
|
||||
b++
|
||||
}
|
||||
}
|
||||
@@ -271,8 +271,8 @@ fun foo() {
|
||||
z = 3
|
||||
}
|
||||
fun foo() {
|
||||
y = 10
|
||||
z = 13
|
||||
<!VAL_REASSIGNMENT!>y<!> = 10
|
||||
<!VAL_REASSIGNMENT!>z<!> = 13
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -290,12 +290,12 @@ class TestObjectExpression() {
|
||||
x = 1
|
||||
}
|
||||
fun inner1() {
|
||||
y = 101
|
||||
a = 231
|
||||
<!VAL_REASSIGNMENT!>y<!> = 101
|
||||
<!VAL_REASSIGNMENT!>a<!> = 231
|
||||
}
|
||||
fun inner2() {
|
||||
y = 101
|
||||
a = 231
|
||||
<!VAL_REASSIGNMENT!>y<!> = 101
|
||||
<!VAL_REASSIGNMENT!>a<!> = 231
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -311,7 +311,7 @@ object TestObjectDeclaration {
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
y = 10
|
||||
<!VAL_REASSIGNMENT!>y<!> = 10
|
||||
val i: Int
|
||||
if (1 < 3) {
|
||||
i = 10
|
||||
@@ -338,11 +338,11 @@ class M() {
|
||||
}
|
||||
|
||||
fun test(m : M) {
|
||||
m.x = 23
|
||||
m.<!VAL_REASSIGNMENT!>x<!> = 23
|
||||
m.y = 23
|
||||
}
|
||||
|
||||
fun test1(m : M) {
|
||||
m.x++
|
||||
m.<!VAL_REASSIGNMENT!>x<!>++
|
||||
m.y--
|
||||
}
|
||||
|
||||
+1
-1
@@ -86,5 +86,5 @@ class My {
|
||||
<!MUST_BE_INITIALIZED!>val top: Int<!>
|
||||
|
||||
fun init() {
|
||||
top = 1
|
||||
<!VAL_REASSIGNMENT!>top<!> = 1
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ fun foo(a: A) {
|
||||
get() = 42
|
||||
}
|
||||
|
||||
a.z = 23
|
||||
o.y = 11 //Should be an error here
|
||||
a.<!VAL_REASSIGNMENT!>z<!> = 23
|
||||
o.<!VAL_REASSIGNMENT!>y<!> = 11 //Should be an error here
|
||||
}
|
||||
|
||||
class A() {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
//KT-897 Don't allow assignment to a property before it is defined
|
||||
|
||||
package kt897
|
||||
|
||||
class A() {
|
||||
init {
|
||||
<!INITIALIZATION_BEFORE_DECLARATION, VAL_REASSIGNMENT!>i<!> = 11
|
||||
}
|
||||
val i : Int? = null // must be an error
|
||||
|
||||
init {
|
||||
<!INITIALIZATION_BEFORE_DECLARATION!>j<!> = 1
|
||||
}
|
||||
var j : Int = 2
|
||||
|
||||
init {
|
||||
<!INITIALIZATION_BEFORE_DECLARATION!>k<!> = 3
|
||||
}
|
||||
val k : Int
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
//KT-897 Don't allow assignment to a property before it is defined
|
||||
|
||||
package kt897
|
||||
|
||||
Vendored
+3
-3
@@ -6,9 +6,9 @@ class Outer {
|
||||
outerProp // use of outerProp is ok because we're suppose that Outer instance should be initialized
|
||||
this@Outer.outerProp
|
||||
|
||||
this@Outer.outerProp = "1"
|
||||
outerProp = "2" // do not repeat the same diagnostic with this receiver of outer class
|
||||
outer.outerProp = "3"
|
||||
this@Outer.<!VAL_REASSIGNMENT!>outerProp<!> = "1"
|
||||
<!VAL_REASSIGNMENT!>outerProp<!> = "2" // do not repeat the same diagnostic with this receiver of outer class
|
||||
outer.<!VAL_REASSIGNMENT!>outerProp<!> = "3"
|
||||
|
||||
innerProp = "4" + inner.innerProp
|
||||
this@Inner.innerProp = "5"
|
||||
|
||||
@@ -7,7 +7,7 @@ open class M() {
|
||||
class N() : M() {
|
||||
val a : Int
|
||||
get() {
|
||||
super.b = super.b + 1
|
||||
super.<!VAL_REASSIGNMENT!>b<!> = super.b + 1
|
||||
return super.b + 1
|
||||
}
|
||||
override val b: Int = a + 1
|
||||
|
||||
+1
-1
@@ -63,6 +63,6 @@ class InitializationForbiddenInNonInitSection {
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val x: Int<!>
|
||||
|
||||
fun setup() {
|
||||
myRun { x = 42 }
|
||||
myRun { <!VAL_REASSIGNMENT!>x<!> = 42 }
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ class Case1() {
|
||||
|
||||
fun case2() {
|
||||
var b= Case2()
|
||||
--b.a
|
||||
--b.<!VAL_REASSIGNMENT!>a<!>
|
||||
}
|
||||
|
||||
class Case2() {
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ class Case1() {
|
||||
|
||||
fun case2() {
|
||||
var b= Case2()
|
||||
++b.a
|
||||
++b.<!VAL_REASSIGNMENT!>a<!>
|
||||
}
|
||||
|
||||
class Case2() {
|
||||
|
||||
+6
-6
@@ -7,8 +7,8 @@
|
||||
*/
|
||||
fun case1() {
|
||||
val x : Case1? = Case1()
|
||||
x.x = "0"
|
||||
x?.x = "0"
|
||||
x.<!VAL_REASSIGNMENT!>x<!> = "0"
|
||||
x?.<!VAL_REASSIGNMENT!>x<!> = "0"
|
||||
<!VARIABLE_EXPECTED!>x::x<!> = TODO()
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ class Case1{
|
||||
*/
|
||||
fun case2() {
|
||||
val x : Case2? = Case2(null)
|
||||
x.x = "0"
|
||||
x?.x = "0"
|
||||
x.<!VAL_REASSIGNMENT!>x<!> = "0"
|
||||
x?.<!VAL_REASSIGNMENT!>x<!> = "0"
|
||||
<!VARIABLE_EXPECTED!>x::x<!> = TODO()
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ class Case2(val x: Any?) {}
|
||||
*/
|
||||
fun case3() {
|
||||
val x : Case3? = Case3()
|
||||
x.x = "0"
|
||||
x?.x = "0"
|
||||
x.<!VAL_REASSIGNMENT!>x<!> = "0"
|
||||
x?.<!VAL_REASSIGNMENT!>x<!> = "0"
|
||||
<!VARIABLE_EXPECTED!>x::x<!> = TODO()
|
||||
}
|
||||
|
||||
|
||||
@@ -32,5 +32,5 @@ fun `should not report an error for assign return type for unannotated class`()
|
||||
data class IntTask(val input: IntProperty)
|
||||
|
||||
val task = IntTask(IntProperty(42))
|
||||
task.input = <!ASSIGNMENT_TYPE_MISMATCH!>42<!>
|
||||
task.<!VAL_REASSIGNMENT!>input<!> = <!ASSIGNMENT_TYPE_MISMATCH!>42<!>
|
||||
}
|
||||
|
||||
@@ -14,16 +14,16 @@ data class Task(val input: StringProperty)
|
||||
|
||||
fun `should not work with assignment when there is no annotation on a type`() {
|
||||
val task = Task(StringProperty("Fail"))
|
||||
task.input = <!ASSIGNMENT_TYPE_MISMATCH!>"OK"<!>
|
||||
task.input = StringProperty("OK")
|
||||
task.<!VAL_REASSIGNMENT!>input<!> = <!ASSIGNMENT_TYPE_MISMATCH!>"OK"<!>
|
||||
task.<!VAL_REASSIGNMENT!>input<!> = StringProperty("OK")
|
||||
task.apply {
|
||||
input = <!ASSIGNMENT_TYPE_MISMATCH!>"OK"<!>
|
||||
<!VAL_REASSIGNMENT!>input<!> = <!ASSIGNMENT_TYPE_MISMATCH!>"OK"<!>
|
||||
}
|
||||
task.apply {
|
||||
input = StringProperty("OK")
|
||||
<!VAL_REASSIGNMENT!>input<!> = StringProperty("OK")
|
||||
}
|
||||
task.input = <!ASSIGNMENT_TYPE_MISMATCH!>42<!>
|
||||
task.<!VAL_REASSIGNMENT!>input<!> = <!ASSIGNMENT_TYPE_MISMATCH!>42<!>
|
||||
task.apply {
|
||||
input = <!ASSIGNMENT_TYPE_MISMATCH!>42<!>
|
||||
<!VAL_REASSIGNMENT!>input<!> = <!ASSIGNMENT_TYPE_MISMATCH!>42<!>
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user