[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 {
|
public void testInitializationInTry() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfa/initializationInTry.kt");
|
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
|
@Nested
|
||||||
|
|||||||
+10
@@ -940,6 +940,16 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
|||||||
public void testInitializationInTry() throws Exception {
|
public void testInitializationInTry() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfa/initializationInTry.kt");
|
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")
|
@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>() }
|
d2.bar(1, "").checkType { _<String>() }
|
||||||
|
|
||||||
d3.x.checkType { _<String>() }
|
d3.x.checkType { _<String>() }
|
||||||
d3.x = ""
|
d3.<!VAL_REASSIGNMENT!>x<!> = ""
|
||||||
d3.foo().checkType { _<String?>() }
|
d3.foo().checkType { _<String?>() }
|
||||||
d3.bar(1, "").checkType { _<String?>() }
|
d3.bar(1, "").checkType { _<String?>() }
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ class B(p0: String) {
|
|||||||
p3 = p1
|
p3 = p1
|
||||||
}
|
}
|
||||||
init {
|
init {
|
||||||
p1 = <!ASSIGNMENT_TYPE_MISMATCH!>p0.length<!>
|
<!VAL_REASSIGNMENT!>p1<!> = <!ASSIGNMENT_TYPE_MISMATCH!>p0.length<!>
|
||||||
p3 = ""
|
p3 = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
@@ -1086,6 +1086,18 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
|
|||||||
public void testInitializationInTry() throws Exception {
|
public void testInitializationInTry() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfa/initializationInTry.kt");
|
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
|
@Nested
|
||||||
|
|||||||
+12
@@ -1086,6 +1086,18 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
public void testInitializationInTry() throws Exception {
|
public void testInitializationInTry() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/cfa/initializationInTry.kt");
|
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
|
@Nested
|
||||||
|
|||||||
+1
-1
@@ -73,7 +73,7 @@ object FirPropertyInitializationAnalyzer : AbstractFirPropertyInitializationChec
|
|||||||
} else {
|
} else {
|
||||||
reporter.reportOn(node.fir.lValue.source, FirErrors.CAPTURED_MEMBER_VAL_INITIALIZATION, symbol, context)
|
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)
|
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) {
|
override fun visitVariableAssignmentNode(node: VariableAssignmentNode) {
|
||||||
val symbol = node.fir.calleeReference.toResolvedPropertySymbol() ?: return
|
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.
|
// Check if this variable assignment is inside a lambda or a local function.
|
||||||
if (lambdaOrLocalFunctionStack.isEmpty()) return
|
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.context.findClosest
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
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.FirPropertyAccessor
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.hasBackingField
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression
|
import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
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.FirBackingFieldReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirThisReference
|
import org.jetbrains.kotlin.fir.references.FirThisReference
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
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.references.toResolvedValueParameterSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ExpressionReceiverValue
|
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.SymbolInternals
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
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
|
import org.jetbrains.kotlin.fir.visibilityChecker
|
||||||
|
|
||||||
object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker() {
|
object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker() {
|
||||||
@@ -32,6 +42,7 @@ object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker()
|
|||||||
checkValReassignmentViaBackingField(expression, context, reporter)
|
checkValReassignmentViaBackingField(expression, context, reporter)
|
||||||
checkValReassignmentOnValueParameter(expression, context, reporter)
|
checkValReassignmentOnValueParameter(expression, context, reporter)
|
||||||
checkAssignmentToThis(expression, context, reporter)
|
checkAssignmentToThis(expression, context, reporter)
|
||||||
|
checkValReassignmentOfNonLocalProperty(expression, context, reporter)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkInvisibleSetter(
|
private fun checkInvisibleSetter(
|
||||||
@@ -114,4 +125,41 @@ object FirReassignmentAndInvisibleSetterChecker : FirVariableAssignmentChecker()
|
|||||||
reporter.reportOn(expression.lValue.source, FirErrors.VARIABLE_EXPECTED, context)
|
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: JS, NATIVE
|
||||||
|
// IGNORE_BACKEND_K2: ANY
|
||||||
|
// FIR_STATUS: KT-35565
|
||||||
// java.lang.AssertionError
|
// java.lang.AssertionError
|
||||||
// at org.jetbrains.kotlin.js.translate.context.TranslationContext.getDispatchReceiver(TranslationContext.java:590)
|
// at org.jetbrains.kotlin.js.translate.context.TranslationContext.getDispatchReceiver(TranslationContext.java:590)
|
||||||
// at org.jetbrains.kotlin.js.translate.utils.TranslationUtils.backingFieldReference(TranslationUtils.java:237)
|
// at org.jetbrains.kotlin.js.translate.utils.TranslationUtils.backingFieldReference(TranslationUtils.java:237)
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
|
// IGNORE_BACKEND_K2: ANY
|
||||||
|
// FIR_STATUS: KT-35565
|
||||||
|
|
||||||
// This test should become irrelevant after KT-35565 is fixed.
|
// This test should become irrelevant after KT-35565 is fixed.
|
||||||
|
|
||||||
|
|||||||
@@ -11,14 +11,14 @@ class C() : B() {
|
|||||||
this.x = 34
|
this.x = 34
|
||||||
this.b = 123
|
this.b = 123
|
||||||
super.b = 23
|
super.b = 23
|
||||||
this.c = 34
|
this.<!VAL_REASSIGNMENT!>c<!> = 34
|
||||||
super.c = 3535 //repeat for 'c'
|
super.<!VAL_REASSIGNMENT!>c<!> = 3535 //repeat for 'c'
|
||||||
|
|
||||||
<!VARIABLE_EXPECTED!>getInt()<!> = 12
|
<!VARIABLE_EXPECTED!>getInt()<!> = 12
|
||||||
}
|
}
|
||||||
|
|
||||||
fun foo1(c: C) {
|
fun foo1(c: C) {
|
||||||
super.c = 34
|
super.<!VAL_REASSIGNMENT!>c<!> = 34
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bar(c: C) {
|
fun bar(c: C) {
|
||||||
|
|||||||
Vendored
+15
-15
@@ -116,8 +116,8 @@ class AnonymousInitializers(var a: String, val b: String) {
|
|||||||
a = "30"
|
a = "30"
|
||||||
a = "s"
|
a = "s"
|
||||||
|
|
||||||
b = "3"
|
<!VAL_REASSIGNMENT!>b<!> = "3"
|
||||||
b = "tt" //repeat for b
|
<!VAL_REASSIGNMENT!>b<!> = "tt" //repeat for b
|
||||||
}
|
}
|
||||||
|
|
||||||
val i: Int
|
val i: Int
|
||||||
@@ -127,7 +127,7 @@ class AnonymousInitializers(var a: String, val b: String) {
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
x = 11
|
x = 11
|
||||||
z = 10
|
<!VAL_REASSIGNMENT!>z<!> = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
val j: Int
|
val j: Int
|
||||||
@@ -135,7 +135,7 @@ class AnonymousInitializers(var a: String, val b: String) {
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
i = 13
|
i = 13
|
||||||
j = 34
|
<!VAL_REASSIGNMENT!>j<!> = 34
|
||||||
}
|
}
|
||||||
|
|
||||||
val k: String
|
val k: String
|
||||||
@@ -228,13 +228,13 @@ class Outer() {
|
|||||||
|
|
||||||
inner class Inner() {
|
inner class Inner() {
|
||||||
init {
|
init {
|
||||||
a++
|
<!VAL_REASSIGNMENT!>a<!>++
|
||||||
b++
|
b++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
a++
|
<!VAL_REASSIGNMENT!>a<!>++
|
||||||
b++
|
b++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,8 +271,8 @@ fun foo() {
|
|||||||
z = 3
|
z = 3
|
||||||
}
|
}
|
||||||
fun foo() {
|
fun foo() {
|
||||||
y = 10
|
<!VAL_REASSIGNMENT!>y<!> = 10
|
||||||
z = 13
|
<!VAL_REASSIGNMENT!>z<!> = 13
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -290,12 +290,12 @@ class TestObjectExpression() {
|
|||||||
x = 1
|
x = 1
|
||||||
}
|
}
|
||||||
fun inner1() {
|
fun inner1() {
|
||||||
y = 101
|
<!VAL_REASSIGNMENT!>y<!> = 101
|
||||||
a = 231
|
<!VAL_REASSIGNMENT!>a<!> = 231
|
||||||
}
|
}
|
||||||
fun inner2() {
|
fun inner2() {
|
||||||
y = 101
|
<!VAL_REASSIGNMENT!>y<!> = 101
|
||||||
a = 231
|
<!VAL_REASSIGNMENT!>a<!> = 231
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -311,7 +311,7 @@ object TestObjectDeclaration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
y = 10
|
<!VAL_REASSIGNMENT!>y<!> = 10
|
||||||
val i: Int
|
val i: Int
|
||||||
if (1 < 3) {
|
if (1 < 3) {
|
||||||
i = 10
|
i = 10
|
||||||
@@ -338,11 +338,11 @@ class M() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test(m : M) {
|
fun test(m : M) {
|
||||||
m.x = 23
|
m.<!VAL_REASSIGNMENT!>x<!> = 23
|
||||||
m.y = 23
|
m.y = 23
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test1(m : M) {
|
fun test1(m : M) {
|
||||||
m.x++
|
m.<!VAL_REASSIGNMENT!>x<!>++
|
||||||
m.y--
|
m.y--
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -86,5 +86,5 @@ class My {
|
|||||||
<!MUST_BE_INITIALIZED!>val top: Int<!>
|
<!MUST_BE_INITIALIZED!>val top: Int<!>
|
||||||
|
|
||||||
fun init() {
|
fun init() {
|
||||||
top = 1
|
<!VAL_REASSIGNMENT!>top<!> = 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ fun foo(a: A) {
|
|||||||
get() = 42
|
get() = 42
|
||||||
}
|
}
|
||||||
|
|
||||||
a.z = 23
|
a.<!VAL_REASSIGNMENT!>z<!> = 23
|
||||||
o.y = 11 //Should be an error here
|
o.<!VAL_REASSIGNMENT!>y<!> = 11 //Should be an error here
|
||||||
}
|
}
|
||||||
|
|
||||||
class A() {
|
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
|
//KT-897 Don't allow assignment to a property before it is defined
|
||||||
|
|
||||||
package kt897
|
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
|
outerProp // use of outerProp is ok because we're suppose that Outer instance should be initialized
|
||||||
this@Outer.outerProp
|
this@Outer.outerProp
|
||||||
|
|
||||||
this@Outer.outerProp = "1"
|
this@Outer.<!VAL_REASSIGNMENT!>outerProp<!> = "1"
|
||||||
outerProp = "2" // do not repeat the same diagnostic with this receiver of outer class
|
<!VAL_REASSIGNMENT!>outerProp<!> = "2" // do not repeat the same diagnostic with this receiver of outer class
|
||||||
outer.outerProp = "3"
|
outer.<!VAL_REASSIGNMENT!>outerProp<!> = "3"
|
||||||
|
|
||||||
innerProp = "4" + inner.innerProp
|
innerProp = "4" + inner.innerProp
|
||||||
this@Inner.innerProp = "5"
|
this@Inner.innerProp = "5"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ open class M() {
|
|||||||
class N() : M() {
|
class N() : M() {
|
||||||
val a : Int
|
val a : Int
|
||||||
get() {
|
get() {
|
||||||
super.b = super.b + 1
|
super.<!VAL_REASSIGNMENT!>b<!> = super.b + 1
|
||||||
return super.b + 1
|
return super.b + 1
|
||||||
}
|
}
|
||||||
override val b: Int = a + 1
|
override val b: Int = a + 1
|
||||||
|
|||||||
+1
-1
@@ -63,6 +63,6 @@ class InitializationForbiddenInNonInitSection {
|
|||||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val x: Int<!>
|
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val x: Int<!>
|
||||||
|
|
||||||
fun setup() {
|
fun setup() {
|
||||||
myRun { x = 42 }
|
myRun { <!VAL_REASSIGNMENT!>x<!> = 42 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@ class Case1() {
|
|||||||
|
|
||||||
fun case2() {
|
fun case2() {
|
||||||
var b= Case2()
|
var b= Case2()
|
||||||
--b.a
|
--b.<!VAL_REASSIGNMENT!>a<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
class Case2() {
|
class Case2() {
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@ class Case1() {
|
|||||||
|
|
||||||
fun case2() {
|
fun case2() {
|
||||||
var b= Case2()
|
var b= Case2()
|
||||||
++b.a
|
++b.<!VAL_REASSIGNMENT!>a<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
class Case2() {
|
class Case2() {
|
||||||
|
|||||||
+6
-6
@@ -7,8 +7,8 @@
|
|||||||
*/
|
*/
|
||||||
fun case1() {
|
fun case1() {
|
||||||
val x : Case1? = Case1()
|
val x : Case1? = Case1()
|
||||||
x.x = "0"
|
x.<!VAL_REASSIGNMENT!>x<!> = "0"
|
||||||
x?.x = "0"
|
x?.<!VAL_REASSIGNMENT!>x<!> = "0"
|
||||||
<!VARIABLE_EXPECTED!>x::x<!> = TODO()
|
<!VARIABLE_EXPECTED!>x::x<!> = TODO()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,8 +23,8 @@ class Case1{
|
|||||||
*/
|
*/
|
||||||
fun case2() {
|
fun case2() {
|
||||||
val x : Case2? = Case2(null)
|
val x : Case2? = Case2(null)
|
||||||
x.x = "0"
|
x.<!VAL_REASSIGNMENT!>x<!> = "0"
|
||||||
x?.x = "0"
|
x?.<!VAL_REASSIGNMENT!>x<!> = "0"
|
||||||
<!VARIABLE_EXPECTED!>x::x<!> = TODO()
|
<!VARIABLE_EXPECTED!>x::x<!> = TODO()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,8 +36,8 @@ class Case2(val x: Any?) {}
|
|||||||
*/
|
*/
|
||||||
fun case3() {
|
fun case3() {
|
||||||
val x : Case3? = Case3()
|
val x : Case3? = Case3()
|
||||||
x.x = "0"
|
x.<!VAL_REASSIGNMENT!>x<!> = "0"
|
||||||
x?.x = "0"
|
x?.<!VAL_REASSIGNMENT!>x<!> = "0"
|
||||||
<!VARIABLE_EXPECTED!>x::x<!> = TODO()
|
<!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)
|
data class IntTask(val input: IntProperty)
|
||||||
|
|
||||||
val task = IntTask(IntProperty(42))
|
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`() {
|
fun `should not work with assignment when there is no annotation on a type`() {
|
||||||
val task = Task(StringProperty("Fail"))
|
val task = Task(StringProperty("Fail"))
|
||||||
task.input = <!ASSIGNMENT_TYPE_MISMATCH!>"OK"<!>
|
task.<!VAL_REASSIGNMENT!>input<!> = <!ASSIGNMENT_TYPE_MISMATCH!>"OK"<!>
|
||||||
task.input = StringProperty("OK")
|
task.<!VAL_REASSIGNMENT!>input<!> = StringProperty("OK")
|
||||||
task.apply {
|
task.apply {
|
||||||
input = <!ASSIGNMENT_TYPE_MISMATCH!>"OK"<!>
|
<!VAL_REASSIGNMENT!>input<!> = <!ASSIGNMENT_TYPE_MISMATCH!>"OK"<!>
|
||||||
}
|
}
|
||||||
task.apply {
|
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 {
|
task.apply {
|
||||||
input = <!ASSIGNMENT_TYPE_MISMATCH!>42<!>
|
<!VAL_REASSIGNMENT!>input<!> = <!ASSIGNMENT_TYPE_MISMATCH!>42<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user