From 7e1c2cfd36f13bd1ea9106fce6400c88a569c383 Mon Sep 17 00:00:00 2001 From: Nick Date: Fri, 14 Aug 2020 11:36:14 +0300 Subject: [PATCH] [FIR] Add diagnostic INAPPLICABLE_LATEINIT_MODIFIER + some builtin types --- .../inapplicableLateinitModifier.kt | 38 +++++++ .../inapplicableLateinitModifier.txt | 102 ++++++++++++++++++ .../resolve/fromBuilder/simpleClass.kt | 2 +- .../fir/FirDiagnosticsTestGenerated.java | 5 + ...DiagnosticsWithLightTreeTestGenerated.java | 5 + .../declaration/DefaultDeclarationCheckers.kt | 1 + .../FirInapplicableLateinitChecker.kt | 79 ++++++++++++++ .../diagnostics/FirDefaultErrorMessages.kt | 2 + .../fir/analysis/diagnostics/FirErrors.kt | 1 + .../org/jetbrains/kotlin/fir/FirSession.kt | 6 ++ .../types/impl/FirImplicitBuiltinTypeRef.kt | 30 ++++++ .../cli/jvm/inapplicableLateinitModifier.args | 4 + .../cli/jvm/inapplicableLateinitModifier.kt | 24 +++++ .../cli/jvm/inapplicableLateinitModifier.out | 52 +++++++++ ...ocalVariablesWithTypeParameters_1_3.fir.kt | 2 +- ...ocalVariablesWithTypeParameters_1_4.fir.kt | 2 +- .../local/inapplicableLateinitModifier.fir.kt | 10 +- .../lateinit/modifierApplicability.fir.kt | 32 +++--- .../modifierApplicability_lv12.fir.kt | 32 +++--- .../properties/lateinitOnTopLevel.fir.kt | 10 +- .../kotlin/cli/CliTestGenerated.java | 5 + 21 files changed, 399 insertions(+), 45 deletions(-) create mode 100644 compiler/fir/analysis-tests/testData/resolve/diagnostics/inapplicableLateinitModifier.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/diagnostics/inapplicableLateinitModifier.txt create mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInapplicableLateinitChecker.kt create mode 100644 compiler/testData/cli/jvm/inapplicableLateinitModifier.args create mode 100644 compiler/testData/cli/jvm/inapplicableLateinitModifier.kt create mode 100644 compiler/testData/cli/jvm/inapplicableLateinitModifier.out diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/inapplicableLateinitModifier.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/inapplicableLateinitModifier.kt new file mode 100644 index 00000000000..4479b9b9485 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/inapplicableLateinitModifier.kt @@ -0,0 +1,38 @@ +object Delegate { + operator fun getValue(instance: Any?, property: Any) : String = "" + operator fun setValue(instance: Any?, property: Any, value: String) {} +} + +lateinit var test: Int +lateinit var kest by Delegate + +lateinit var good: String + +class A { + lateinit val fest = "10" + lateinit var mest: String + lateinit var xest: String? + lateinit var nest: Int + lateinit var west: Char + lateinit var qest: Boolean + lateinit var aest: Short + lateinit var hest: Byte + lateinit var jest: Long + lateinit val dest: String + get() = "KEKER" +} + +class B { + lateinit var best: T +} + +class C { + lateinit var pest: K + lateinit var vest: K? +} + +fun rest() { + lateinit var i: Int + lateinit var a: A + lateinit var b: B = B() +} \ No newline at end of file diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/inapplicableLateinitModifier.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/inapplicableLateinitModifier.txt new file mode 100644 index 00000000000..25ee479401a --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/inapplicableLateinitModifier.txt @@ -0,0 +1,102 @@ +FILE: inapplicableLateinitModifier.kt + public final object Delegate : R|kotlin/Any| { + private constructor(): R|Delegate| { + super() + } + + public final operator fun getValue(instance: R|kotlin/Any?|, property: R|kotlin/Any|): R|kotlin/String| { + ^getValue String() + } + + public final operator fun setValue(instance: R|kotlin/Any?|, property: R|kotlin/Any|, value: R|kotlin/String|): R|kotlin/Unit| { + } + + } + public final lateinit var test: R|kotlin/Int| + public get(): R|kotlin/Int| + public set(value: R|kotlin/Int|): R|kotlin/Unit| + public final lateinit var kest: R|kotlin/String|by Q|Delegate| + public get(): R|kotlin/String| { + ^ D|/kest|.R|/Delegate.getValue|(Null(null), ::R|/kest|) + } + public set(: R|kotlin/String|): R|kotlin/Unit| { + D|/kest|.R|/Delegate.setValue|(Null(null), ::R|/kest|, R|/kest|) + } + public final lateinit var good: R|kotlin/String| + public get(): R|kotlin/String| + public set(value: R|kotlin/String|): R|kotlin/Unit| + public final class A : R|kotlin/Any| { + public constructor(): R|A| { + super() + } + + public final lateinit val fest: R|kotlin/String| = String(10) + public get(): R|kotlin/String| + + public final lateinit var mest: R|kotlin/String| + public get(): R|kotlin/String| + public set(value: R|kotlin/String|): R|kotlin/Unit| + + public final lateinit var xest: R|kotlin/String?| + public get(): R|kotlin/String?| + public set(value: R|kotlin/String?|): R|kotlin/Unit| + + public final lateinit var nest: R|kotlin/Int| + public get(): R|kotlin/Int| + public set(value: R|kotlin/Int|): R|kotlin/Unit| + + public final lateinit var west: R|kotlin/Char| + public get(): R|kotlin/Char| + public set(value: R|kotlin/Char|): R|kotlin/Unit| + + public final lateinit var qest: R|kotlin/Boolean| + public get(): R|kotlin/Boolean| + public set(value: R|kotlin/Boolean|): R|kotlin/Unit| + + public final lateinit var aest: R|kotlin/Short| + public get(): R|kotlin/Short| + public set(value: R|kotlin/Short|): R|kotlin/Unit| + + public final lateinit var hest: R|kotlin/Byte| + public get(): R|kotlin/Byte| + public set(value: R|kotlin/Byte|): R|kotlin/Unit| + + public final lateinit var jest: R|kotlin/Long| + public get(): R|kotlin/Long| + public set(value: R|kotlin/Long|): R|kotlin/Unit| + + public final lateinit val dest: R|kotlin/String| + public get(): R|kotlin/String| { + ^ String(KEKER) + } + + } + public final class B : R|kotlin/Any| { + public constructor(): R|B| { + super() + } + + public final lateinit var best: R|T| + public get(): R|T| + public set(value: R|T|): R|kotlin/Unit| + + } + public final class C : R|kotlin/Any| { + public constructor(): R|C| { + super() + } + + public final lateinit var pest: R|K| + public get(): R|K| + public set(value: R|K|): R|kotlin/Unit| + + public final lateinit var vest: R|K?| + public get(): R|K?| + public set(value: R|K?|): R|kotlin/Unit| + + } + public final fun rest(): R|kotlin/Unit| { + lateinit lvar i: R|kotlin/Int| + lateinit lvar a: R|A| + lateinit lvar b: R|B| = R|/B.B|() + } diff --git a/compiler/fir/analysis-tests/testData/resolve/fromBuilder/simpleClass.kt b/compiler/fir/analysis-tests/testData/resolve/fromBuilder/simpleClass.kt index 018c484f32b..b35d86be327 100644 --- a/compiler/fir/analysis-tests/testData/resolve/fromBuilder/simpleClass.kt +++ b/compiler/fir/analysis-tests/testData/resolve/fromBuilder/simpleClass.kt @@ -15,7 +15,7 @@ class SomeClass : SomeInterface { get() = true set(value) {} - lateinit var fau: Double + lateinit var fau: Double } inline class InlineClass \ No newline at end of file diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java index a7e9be1e2a5..ffe1873fd81 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java @@ -961,6 +961,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/explicitDelegationCallRequired.kt"); } + @TestMetadata("inapplicableLateinitModifier.kt") + public void testInapplicableLateinitModifier() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/inapplicableLateinitModifier.kt"); + } + @TestMetadata("incompatibleModifiers.kt") public void testIncompatibleModifiers() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/incompatibleModifiers.kt"); diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java index c389ebf3906..a964f8408a0 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java @@ -961,6 +961,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/explicitDelegationCallRequired.kt"); } + @TestMetadata("inapplicableLateinitModifier.kt") + public void testInapplicableLateinitModifier() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/inapplicableLateinitModifier.kt"); + } + @TestMetadata("incompatibleModifiers.kt") public void testIncompatibleModifiers() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/incompatibleModifiers.kt"); diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/DefaultDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/DefaultDeclarationCheckers.kt index b98fddb6e36..5b4ddeb8194 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/DefaultDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/DefaultDeclarationCheckers.kt @@ -39,6 +39,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirInterfaceWithSuperclassChecker, FirEnumClassSimpleChecker, FirSealedSupertypeChecker, + FirInapplicableLateinitChecker, ) override val regularClassCheckers: List = listOf( diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInapplicableLateinitChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInapplicableLateinitChecker.kt new file mode 100644 index 00000000000..8abac928b23 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInapplicableLateinitChecker.kt @@ -0,0 +1,79 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.checkers.declaration + +import org.jetbrains.kotlin.fir.FirFakeSourceElementKind +import org.jetbrains.kotlin.fir.FirSourceElement +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.types.ConeKotlinType +import org.jetbrains.kotlin.fir.types.ConeTypeParameterType +import org.jetbrains.kotlin.fir.types.coneType +import org.jetbrains.kotlin.fir.types.isNullable + +object FirInapplicableLateinitChecker : FirMemberDeclarationChecker() { + var primitives: Set? = null + + private fun getPrimitiveTypes(context: CheckerContext) = primitives ?: mutableSetOf().apply { + with(context.session.builtinTypes) { + add(intType.coneType) + add(booleanType.coneType) + add(charType.coneType) + add(shortType.coneType) + add(byteType.coneType) + add(longType.coneType) + add(doubleType.coneType) + add(floatType.coneType) + } + primitives = this + } + + override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { + if (declaration !is FirProperty || !declaration.isLateInit) { + return + } + + when { + declaration.isVal -> + reporter.report(declaration.source, "is allowed only on mutable properties") + + declaration.initializer != null -> if (declaration.isLocal) { + reporter.report(declaration.source, "is not allowed on local variables with initializer") + } else { + reporter.report(declaration.source, "is not allowed on properties with initializer") + } + + declaration.delegate != null -> + reporter.report(declaration.source, "is not allowed on delegated properties") + + declaration.isNullable() -> + reporter.report(declaration.source, "is not allowed on properties of a type with nullable upper bound") + + declaration.returnTypeRef.coneType in getPrimitiveTypes(context) -> if (declaration.isLocal) { + reporter.report(declaration.source, "is not allowed on local variables of primitive types") + } else { + reporter.report(declaration.source, "is not allowed on properties of primitive types") + } + + declaration.hasGetter() || declaration.hasSetter() -> + reporter.report(declaration.source, "is not allowed on properties with a custom getter or setter") + } + } + + private fun FirProperty.isNullable() = when (val type = returnTypeRef.coneType) { + is ConeTypeParameterType -> type.isNullable || type.lookupTag.typeParameterSymbol.fir.bounds.any { it.coneType.isNullable } + else -> type.isNullable + } + + private fun FirProperty.hasGetter() = getter != null && getter?.source != null && getter?.source?.kind !is FirFakeSourceElementKind + private fun FirProperty.hasSetter() = setter != null && setter?.source != null && setter?.source?.kind !is FirFakeSourceElementKind + + private fun DiagnosticReporter.report(source: FirSourceElement?, target: String) { + source?.let { report(FirErrors.INAPPLICABLE_LATEINIT_MODIFIER.on(it, target)) } + } +} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index d1b280b5e5d..cae34159115 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -50,6 +50,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_CONST_EXP import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_UNDERSCORE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_CANDIDATE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_INFIX_MODIFIER +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_LATEINIT_MODIFIER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INCOMPATIBLE_MODIFIERS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INFERENCE_ERROR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INTERFACE_WITH_SUPERCLASS @@ -234,6 +235,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { // Applicability map.put(NONE_APPLICABLE, "None of the following functions are applicable: {0}", SYMBOLS) map.put(INAPPLICABLE_CANDIDATE, "Inapplicable candidate(s): {0}", SYMBOL) + map.put(INAPPLICABLE_LATEINIT_MODIFIER, "''lateinit'' modifier {0}", TO_STRING) // Ambiguity map.put(AMBIGUITY, "Ambiguity between candidates: {0}", SYMBOLS) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 557a52420e5..6889f3e4ecf 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -108,6 +108,7 @@ object FirErrors { // Applicability val NONE_APPLICABLE by error1>>() val INAPPLICABLE_CANDIDATE by error1>() + val INAPPLICABLE_LATEINIT_MODIFIER by error1() // Ambiguity val AMBIGUITY by error1>>() diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt index ca988ffd4f1..8eaa9b616c4 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt @@ -54,8 +54,14 @@ class BuiltinTypes { val enumType: FirImplicitBuiltinTypeRef = FirImplicitEnumTypeRef(null) val annotationType: FirImplicitBuiltinTypeRef = FirImplicitAnnotationTypeRef(null) val booleanType: FirImplicitBuiltinTypeRef = FirImplicitBooleanTypeRef(null) + val byteType: FirImplicitBuiltinTypeRef = FirImplicitByteTypeRef(null) + val shortType: FirImplicitBuiltinTypeRef = FirImplicitShortTypeRef(null) val intType: FirImplicitBuiltinTypeRef = FirImplicitIntTypeRef(null) + val longType: FirImplicitBuiltinTypeRef = FirImplicitLongTypeRef(null) + val doubleType: FirImplicitBuiltinTypeRef = FirImplicitDoubleTypeRef(null) + val floatType: FirImplicitBuiltinTypeRef = FirImplicitFloatTypeRef(null) val nothingType: FirImplicitBuiltinTypeRef = FirImplicitNothingTypeRef(null) val nullableNothingType: FirImplicitBuiltinTypeRef = FirImplicitNullableNothingTypeRef(null) + val charType: FirImplicitBuiltinTypeRef = FirImplicitCharTypeRef(null) val stringType: FirImplicitBuiltinTypeRef = FirImplicitStringTypeRef(null) } \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirImplicitBuiltinTypeRef.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirImplicitBuiltinTypeRef.kt index 8481c1b4740..c579d8e6817 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirImplicitBuiltinTypeRef.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/impl/FirImplicitBuiltinTypeRef.kt @@ -72,10 +72,30 @@ class FirImplicitBooleanTypeRef( source: FirSourceElement? ) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Boolean) +class FirImplicitByteTypeRef( + source: FirSourceElement? +) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Byte) + +class FirImplicitShortTypeRef( + source: FirSourceElement? +) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Short) + class FirImplicitIntTypeRef( source: FirSourceElement? ) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Int) +class FirImplicitLongTypeRef( + source: FirSourceElement? +) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Long) + +class FirImplicitDoubleTypeRef( + source: FirSourceElement? +) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Double) + +class FirImplicitFloatTypeRef( + source: FirSourceElement? +) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Float) + class FirImplicitNothingTypeRef( source: FirSourceElement? ) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Nothing) @@ -84,6 +104,10 @@ class FirImplicitNullableNothingTypeRef( source: FirSourceElement? ) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Nothing, isNullable = true) +class FirImplicitCharTypeRef( + source: FirSourceElement? +) : FirImplicitBuiltinTypeRef(source, StandardClassIds.Char) + class FirImplicitStringTypeRef( source: FirSourceElement? ) : FirImplicitBuiltinTypeRef(source, StandardClassIds.String) @@ -146,9 +170,15 @@ fun FirImplicitBuiltinTypeRef.withFakeSource(kind: FirFakeSourceElementKind): Fi is FirImplicitEnumTypeRef -> FirImplicitEnumTypeRef(newSource) is FirImplicitAnnotationTypeRef -> FirImplicitAnnotationTypeRef(newSource) is FirImplicitBooleanTypeRef -> FirImplicitBooleanTypeRef(newSource) + is FirImplicitByteTypeRef -> FirImplicitByteTypeRef(newSource) + is FirImplicitShortTypeRef -> FirImplicitShortTypeRef(newSource) is FirImplicitIntTypeRef -> FirImplicitIntTypeRef(newSource) + is FirImplicitLongTypeRef -> FirImplicitLongTypeRef(newSource) + is FirImplicitDoubleTypeRef -> FirImplicitDoubleTypeRef(newSource) + is FirImplicitFloatTypeRef -> FirImplicitFloatTypeRef(newSource) is FirImplicitNothingTypeRef -> FirImplicitNothingTypeRef(newSource) is FirImplicitNullableNothingTypeRef -> FirImplicitNullableNothingTypeRef(newSource) + is FirImplicitCharTypeRef -> FirImplicitCharTypeRef(newSource) is FirImplicitStringTypeRef -> FirImplicitStringTypeRef(newSource) is FirImplicitKPropertyTypeRef -> FirImplicitKPropertyTypeRef( newSource, diff --git a/compiler/testData/cli/jvm/inapplicableLateinitModifier.args b/compiler/testData/cli/jvm/inapplicableLateinitModifier.args new file mode 100644 index 00000000000..7e0831dbd85 --- /dev/null +++ b/compiler/testData/cli/jvm/inapplicableLateinitModifier.args @@ -0,0 +1,4 @@ +$TESTDATA_DIR$/inapplicableLateinitModifier.kt +-Xuse-fir +-d +$TEMP_DIR$ diff --git a/compiler/testData/cli/jvm/inapplicableLateinitModifier.kt b/compiler/testData/cli/jvm/inapplicableLateinitModifier.kt new file mode 100644 index 00000000000..ea8130963d9 --- /dev/null +++ b/compiler/testData/cli/jvm/inapplicableLateinitModifier.kt @@ -0,0 +1,24 @@ +object Delegate { + operator fun getValue(instance: Any?, property: Any) : String = "" + operator fun setValue(instance: Any?, property: Any, value: String) {} +} + +lateinit var kest by Delegate + +class A { + lateinit val fest = "10" + lateinit var mest: String + lateinit var xest: String? + lateinit var nest: Int + lateinit val dest: String + get() = "KEKER" +} + +class B { + lateinit var best: T +} + +fun rest() { + lateinit var a: A + lateinit var b: B = B() +} \ No newline at end of file diff --git a/compiler/testData/cli/jvm/inapplicableLateinitModifier.out b/compiler/testData/cli/jvm/inapplicableLateinitModifier.out new file mode 100644 index 00000000000..fea5e307797 --- /dev/null +++ b/compiler/testData/cli/jvm/inapplicableLateinitModifier.out @@ -0,0 +1,52 @@ +compiler/testData/cli/jvm/inapplicableLateinitModifier.kt:6:1: error: 'lateinit' modifier is not allowed on properties of primitive types +lateinit var test: Int +^ +compiler/testData/cli/jvm/inapplicableLateinitModifier.kt:7:1: error: 'lateinit' modifier is not allowed on delegated properties +lateinit var kest by Delegate +^ +compiler/testData/cli/jvm/inapplicableLateinitModifier.kt:12:5: error: 'lateinit' modifier is allowed only on mutable properties + lateinit val fest = "10" + ^ +compiler/testData/cli/jvm/inapplicableLateinitModifier.kt:12:5: error: 'lateinit' modifier is not allowed on properties with initializer + lateinit val fest = "10" + ^ +compiler/testData/cli/jvm/inapplicableLateinitModifier.kt:14:5: error: 'lateinit' modifier is not allowed on properties of nullable types + lateinit var xest: String? + ^ +compiler/testData/cli/jvm/inapplicableLateinitModifier.kt:15:5: error: 'lateinit' modifier is not allowed on properties of primitive types + lateinit var nest: Int + ^ +compiler/testData/cli/jvm/inapplicableLateinitModifier.kt:16:5: error: 'lateinit' modifier is not allowed on properties of primitive types + lateinit var west: Char + ^ +compiler/testData/cli/jvm/inapplicableLateinitModifier.kt:17:5: error: 'lateinit' modifier is not allowed on properties of primitive types + lateinit var qest: Boolean + ^ +compiler/testData/cli/jvm/inapplicableLateinitModifier.kt:18:5: error: 'lateinit' modifier is not allowed on properties of primitive types + lateinit var aest: Short + ^ +compiler/testData/cli/jvm/inapplicableLateinitModifier.kt:19:5: error: 'lateinit' modifier is not allowed on properties of primitive types + lateinit var hest: Byte + ^ +compiler/testData/cli/jvm/inapplicableLateinitModifier.kt:20:5: error: 'lateinit' modifier is not allowed on properties of primitive types + lateinit var jest: Long + ^ +compiler/testData/cli/jvm/inapplicableLateinitModifier.kt:21:5: error: 'lateinit' modifier is allowed only on mutable properties + lateinit val dest: String + ^ +compiler/testData/cli/jvm/inapplicableLateinitModifier.kt:21:5: error: 'lateinit' modifier is not allowed on properties with a custom getter or setter + lateinit val dest: String + ^ +compiler/testData/cli/jvm/inapplicableLateinitModifier.kt:26:5: error: 'lateinit' modifier is not allowed on properties of a type with nullable upper bound + lateinit var best: T + ^ +compiler/testData/cli/jvm/inapplicableLateinitModifier.kt:31:5: error: 'lateinit' modifier is not allowed on properties of nullable types + lateinit var vest: K? + ^ +compiler/testData/cli/jvm/inapplicableLateinitModifier.kt:35:5: error: 'lateinit' modifier is not allowed on local variables of primitive types + lateinit var i: Int + ^ +compiler/testData/cli/jvm/inapplicableLateinitModifier.kt:37:5: error: 'lateinit' modifier is not allowed on local variables with initializer + lateinit var b: B = B() + ^ +COMPILATION_ERROR diff --git a/compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_3.fir.kt b/compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_3.fir.kt index cd653b8e32b..aadaa644da0 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_3.fir.kt +++ b/compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_3.fir.kt @@ -9,7 +9,7 @@ fun test() { val a1 = "" val a2 = 0 const val a3 = 0 - lateinit val a4 = 0 + lateinit val a4 = 0 val a5 by Delegate() val a6 by Delegate<T>() } diff --git a/compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.fir.kt b/compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.fir.kt index 7d90342b090..e805b1b2abc 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.fir.kt +++ b/compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.fir.kt @@ -9,7 +9,7 @@ fun test() { val a1 = "" val a2 = 0 const val a3 = 0 - lateinit val a4 = 0 + lateinit val a4 = 0 val a5 by Delegate() val a6 by Delegate<T>() } diff --git a/compiler/testData/diagnostics/tests/lateinit/local/inapplicableLateinitModifier.fir.kt b/compiler/testData/diagnostics/tests/lateinit/local/inapplicableLateinitModifier.fir.kt index c2be8e1ba95..3a70287a722 100644 --- a/compiler/testData/diagnostics/tests/lateinit/local/inapplicableLateinitModifier.fir.kt +++ b/compiler/testData/diagnostics/tests/lateinit/local/inapplicableLateinitModifier.fir.kt @@ -10,9 +10,9 @@ object Delegate { fun test() { - lateinit val test0: Any - lateinit var test1: Int - lateinit var test2: Any? - lateinit var test3: String = "" - lateinit var test4 by Delegate + lateinit val test0: Any + lateinit var test1: Int + lateinit var test2: Any? + lateinit var test3: String = "" + lateinit var test4 by Delegate } diff --git a/compiler/testData/diagnostics/tests/lateinit/modifierApplicability.fir.kt b/compiler/testData/diagnostics/tests/lateinit/modifierApplicability.fir.kt index fec3fbc5ee7..7342803baed 100644 --- a/compiler/testData/diagnostics/tests/lateinit/modifierApplicability.fir.kt +++ b/compiler/testData/diagnostics/tests/lateinit/modifierApplicability.fir.kt @@ -8,12 +8,12 @@ class CustomDelegate { public abstract class A(lateinit var p2: String) { - public lateinit val a: String - lateinit val b: T + public lateinit val a: String + lateinit val b: T private lateinit var c: CharSequence - lateinit val d: String - get + lateinit val d: String + get public lateinit var e: String get @@ -23,22 +23,22 @@ public abstract class A(lateinit var p2: String) { lateinit var a: String } - lateinit var e1: V - lateinit var e2: String? - lateinit var e3: Int - lateinit var e4: Int? - lateinit var e5 = "A" + lateinit var e1: V + lateinit var e2: String? + lateinit var e3: Int + lateinit var e4: Int? + lateinit var e5 = "A" // With initializer, primitive - lateinit var e6 = 3 + lateinit var e6 = 3 - lateinit var e7 by CustomDelegate() + lateinit var e7 by CustomDelegate() - lateinit var e8: String - get() = "A" + lateinit var e8: String + get() = "A" - lateinit var e9: String - set(v) { field = v } + lateinit var e9: String + set(v) { field = v } abstract lateinit var e10: String @@ -47,7 +47,7 @@ public abstract class A(lateinit var p2: String) { lateinit var String.e12: String } -lateinit val topLevel: String +lateinit val topLevel: String lateinit var topLevelMutable: String public interface Intf { diff --git a/compiler/testData/diagnostics/tests/lateinit/modifierApplicability_lv12.fir.kt b/compiler/testData/diagnostics/tests/lateinit/modifierApplicability_lv12.fir.kt index d73c339b13a..aadbc805a75 100644 --- a/compiler/testData/diagnostics/tests/lateinit/modifierApplicability_lv12.fir.kt +++ b/compiler/testData/diagnostics/tests/lateinit/modifierApplicability_lv12.fir.kt @@ -8,12 +8,12 @@ class CustomDelegate { public abstract class A(lateinit var p2: String) { - public lateinit val a: String - lateinit val b: T + public lateinit val a: String + lateinit val b: T private lateinit var c: CharSequence - lateinit val d: String - get + lateinit val d: String + get public lateinit var e: String get @@ -23,22 +23,22 @@ public abstract class A(lateinit var p2: String) { lateinit var a: String } - lateinit var e1: V - lateinit var e2: String? - lateinit var e3: Int - lateinit var e4: Int? - lateinit var e5 = "A" + lateinit var e1: V + lateinit var e2: String? + lateinit var e3: Int + lateinit var e4: Int? + lateinit var e5 = "A" // With initializer, primitive - lateinit var e6 = 3 + lateinit var e6 = 3 - lateinit var e7 by CustomDelegate() + lateinit var e7 by CustomDelegate() - lateinit var e8: String - get() = "A" + lateinit var e8: String + get() = "A" - lateinit var e9: String - set(v) { field = v } + lateinit var e9: String + set(v) { field = v } abstract lateinit var e10: String @@ -47,7 +47,7 @@ public abstract class A(lateinit var p2: String) { lateinit var String.e12: String } -lateinit val topLevel: String +lateinit val topLevel: String lateinit var topLevelMutable: String public interface Intf { diff --git a/compiler/testData/diagnostics/tests/properties/lateinitOnTopLevel.fir.kt b/compiler/testData/diagnostics/tests/properties/lateinitOnTopLevel.fir.kt index f13d54e7923..1abc684500f 100644 --- a/compiler/testData/diagnostics/tests/properties/lateinitOnTopLevel.fir.kt +++ b/compiler/testData/diagnostics/tests/properties/lateinitOnTopLevel.fir.kt @@ -7,8 +7,8 @@ object Delegate { lateinit var testOk: String -lateinit val testErr0: Any -lateinit var testErr1: Int -lateinit var testErr2: Any? -lateinit var testErr3: String = "" -lateinit var testErr4 by Delegate +lateinit val testErr0: Any +lateinit var testErr1: Int +lateinit var testErr2: Any? +lateinit var testErr3: String = "" +lateinit var testErr4 by Delegate diff --git a/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java index aea6cc1c486..39cc87145a9 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java @@ -320,6 +320,11 @@ public class CliTestGenerated extends AbstractCliTest { runTest("compiler/testData/cli/jvm/help.args"); } + @TestMetadata("inapplicableLateinitModifier.args") + public void testInapplicableLateinitModifier() throws Exception { + runTest("compiler/testData/cli/jvm/inapplicableLateinitModifier.args"); + } + @TestMetadata("inlineCycle.args") public void testInlineCycle() throws Exception { runTest("compiler/testData/cli/jvm/inlineCycle.args");