Make LateinitIntrinsicApplicabilityChecker warning for Native and JS

This checker was enabled only on JVM by mistake.
It's now fixed, but we don't want to make it an error in minor release.
So it will be an warning in 1.8.20 and an error in 1.9.0

^KT-27002
This commit is contained in:
Pavel Kunyavskiy
2022-12-13 17:10:14 +01:00
committed by Space Team
parent 17e9a6a781
commit 4928e284f6
18 changed files with 691 additions and 6 deletions
@@ -30,6 +30,18 @@ public class FirOldFrontendNativeDiagnosticsTestGenerated extends AbstractFirNat
runTest("compiler/testData/diagnostics/nativeTests/identifiers.kt");
}
@Test
@TestMetadata("isInitialized.kt")
public void testIsInitialized() throws Exception {
runTest("compiler/testData/diagnostics/nativeTests/isInitialized.kt");
}
@Test
@TestMetadata("isInitializedError.kt")
public void testIsInitializedError() throws Exception {
runTest("compiler/testData/diagnostics/nativeTests/isInitializedError.kt");
}
@Test
@TestMetadata("objCName.kt")
public void testObjCName() throws Exception {
@@ -30,6 +30,18 @@ public class FirOldFrontendNativeDiagnosticsWithLightTreeTestGenerated extends A
runTest("compiler/testData/diagnostics/nativeTests/identifiers.kt");
}
@Test
@TestMetadata("isInitialized.kt")
public void testIsInitialized() throws Exception {
runTest("compiler/testData/diagnostics/nativeTests/isInitialized.kt");
}
@Test
@TestMetadata("isInitializedError.kt")
public void testIsInitializedError() throws Exception {
runTest("compiler/testData/diagnostics/nativeTests/isInitializedError.kt");
}
@Test
@TestMetadata("objCName.kt")
public void testObjCName() throws Exception {
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.load.java.sam.JvmSamConversionOracle
import org.jetbrains.kotlin.resolve.PlatformConfiguratorBase
import org.jetbrains.kotlin.resolve.checkers.BigFunctionTypeAvailabilityChecker
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.resolve.calls.checkers.LateinitIntrinsicApplicabilityChecker
import org.jetbrains.kotlin.resolve.jvm.*
import org.jetbrains.kotlin.resolve.jvm.checkers.*
import org.jetbrains.kotlin.resolve.jvm.multiplatform.JavaActualAnnotationArgumentExtractor
@@ -63,6 +64,7 @@ object JvmPlatformConfigurator : PlatformConfiguratorBase(
EnumDeclaringClassDeprecationChecker,
UpperBoundViolatedInTypealiasConstructorChecker,
JvmSyntheticAssignmentChecker,
LateinitIntrinsicApplicabilityChecker(isWarningInPre19 = false)
),
additionalTypeCheckers = listOf(
@@ -679,6 +679,13 @@ public interface Errors {
DiagnosticFactory1<PsiElement, PropertyDescriptor> LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY =
DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<PsiElement> LATEINIT_INTRINSIC_CALL_ON_NON_LITERAL_WARNING = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<PsiElement> LATEINIT_INTRINSIC_CALL_ON_NON_LATEINIT_WARNING = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<PsiElement> LATEINIT_INTRINSIC_CALL_IN_INLINE_FUNCTION_WARNING = DiagnosticFactory0.create(WARNING);
DiagnosticFactory1<PsiElement, PropertyDescriptor> LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY_WARNING =
DiagnosticFactory1.create(WARNING);
DiagnosticFactory2<KtModifierListOwner, String, ClassDescriptor> ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS =
DiagnosticFactory2.create(ERROR, ABSTRACT_MODIFIER);
@@ -260,6 +260,10 @@ public class DefaultErrorMessages {
MAP.put(LATEINIT_INTRINSIC_CALL_ON_NON_LATEINIT, "This declaration can only be called on a reference to a lateinit property");
MAP.put(LATEINIT_INTRINSIC_CALL_IN_INLINE_FUNCTION, "This declaration can not be used inside an inline function");
MAP.put(LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY, "Backing field of ''{0}'' is not accessible at this point", COMPACT);
MAP.put(LATEINIT_INTRINSIC_CALL_ON_NON_LITERAL_WARNING, "This declaration can only be called on a property literal (e.g. 'Foo::bar'). This warning will become an error in future releases.");
MAP.put(LATEINIT_INTRINSIC_CALL_ON_NON_LATEINIT_WARNING, "This declaration can only be called on a reference to a lateinit property. This warning will become an error in future releases.");
MAP.put(LATEINIT_INTRINSIC_CALL_IN_INLINE_FUNCTION_WARNING, "This declaration can not be used inside an inline function. This warning will become an error in future releases.");
MAP.put(LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY_WARNING, "Backing field of ''{0}'' is not accessible at this point. This warning will become an error in future releases.", COMPACT);
MAP.put(GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY, "Getter visibility must be the same as property visibility");
MAP.put(SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY, "Setter visibility must be the same or less permissive than property visibility");
@@ -61,7 +61,7 @@ private val DEFAULT_CALL_CHECKERS = listOf(
DeprecatedCallChecker, CallReturnsArrayOfNothingChecker(), InfixCallChecker(), OperatorCallChecker(),
ConstructorHeaderCallChecker, ProtectedConstructorCallChecker, ApiVersionCallChecker,
CoroutineSuspendCallChecker, BuilderFunctionsCallChecker, DslScopeViolationCallChecker, MissingDependencyClassChecker,
CallableReferenceCompatibilityChecker(), LateinitIntrinsicApplicabilityChecker,
CallableReferenceCompatibilityChecker(),
UnderscoreUsageChecker, AssigningNamedArgumentToVarargChecker(), ImplicitNothingAsTypeParameterCallChecker,
PrimitiveNumericComparisonCallChecker, LambdaWithSuspendModifierCallChecker,
UselessElvisCallChecker(), ResultTypeWithNullableOperatorsChecker(), NullableVarargArgumentCallChecker,
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.resolve.calls.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
@@ -30,7 +31,7 @@ import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
object LateinitIntrinsicApplicabilityChecker : CallChecker {
class LateinitIntrinsicApplicabilityChecker(val isWarningInPre19: Boolean) : CallChecker {
private val ACCESSIBLE_LATEINIT_PROPERTY_LITERAL = FqName("kotlin.internal.AccessibleLateinitPropertyLiteral")
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
@@ -42,8 +43,14 @@ object LateinitIntrinsicApplicabilityChecker : CallChecker {
if (descriptor.extensionReceiverParameter?.annotations?.hasAnnotation(ACCESSIBLE_LATEINIT_PROPERTY_LITERAL) != true) return
val expression = (resolvedCall.extensionReceiver as? ExpressionReceiver)?.expression?.let(KtPsiUtil::safeDeparenthesize)
fun <T> chooseDiagnostic(ifWarning: T, ifError: T) =
if (isWarningInPre19 && !context.languageVersionSettings.supportsFeature(LanguageFeature.NativeJsProhibitLateinitIsInitalizedIntrinsicWithoutPrivateAccess))
ifWarning
else
ifError
if (expression !is KtCallableReferenceExpression) {
context.trace.report(LATEINIT_INTRINSIC_CALL_ON_NON_LITERAL.on(reportOn))
val diagnostic = chooseDiagnostic(LATEINIT_INTRINSIC_CALL_ON_NON_LITERAL_WARNING, LATEINIT_INTRINSIC_CALL_ON_NON_LITERAL)
context.trace.report(diagnostic.on(reportOn))
} else {
val propertyReferenceResolvedCall = expression.callableReference.getResolvedCall(context.trace.bindingContext) ?: return
val referencedProperty = propertyReferenceResolvedCall.resultingDescriptor
@@ -52,11 +59,20 @@ object LateinitIntrinsicApplicabilityChecker : CallChecker {
}
if (!referencedProperty.isLateInit) {
context.trace.report(LATEINIT_INTRINSIC_CALL_ON_NON_LATEINIT.on(reportOn))
val diagnostic = chooseDiagnostic(LATEINIT_INTRINSIC_CALL_ON_NON_LATEINIT_WARNING, LATEINIT_INTRINSIC_CALL_ON_NON_LATEINIT)
context.trace.report(diagnostic.on(reportOn))
} else if (!isBackingFieldAccessible(referencedProperty, context)) {
context.trace.report(LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY.on(reportOn, referencedProperty))
val diagnostic = chooseDiagnostic(
LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY_WARNING,
LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY
)
context.trace.report(diagnostic.on(reportOn, referencedProperty))
} else if ((context.scope.ownerDescriptor as? FunctionDescriptor)?.isInline == true) {
context.trace.report(LATEINIT_INTRINSIC_CALL_IN_INLINE_FUNCTION.on(reportOn))
val diagnostic = chooseDiagnostic(
LATEINIT_INTRINSIC_CALL_IN_INLINE_FUNCTION_WARNING,
LATEINIT_INTRINSIC_CALL_IN_INLINE_FUNCTION
)
context.trace.report(diagnostic.on(reportOn))
}
}
}
@@ -0,0 +1,106 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -NOTHING_TO_INLINE
// !LANGUAGE: -NativeJsProhibitLateinitIsInitalizedIntrinsicWithoutPrivateAccess
// FILE: stdlibInternal.kt
package kotlin.internal
@Target(AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.BINARY)
internal annotation class AccessibleLateinitPropertyLiteral
// FILE: stdlib.kt
package kotlin
import kotlin.internal.AccessibleLateinitPropertyLiteral
import kotlin.reflect.KProperty0
inline val @receiver:AccessibleLateinitPropertyLiteral KProperty0<*>.isInitialized: Boolean
get() = true
// FILE: test.kt
interface Base {
var x: String
}
open class Foo : Base {
override lateinit var x: String
private lateinit var y: String
var nonLateInit: Int = 1
fun ok() {
val b: Boolean = this::x.isInitialized
val otherInstance = Foo()
otherInstance::x.isInitialized
(this::x).isInitialized
(@Suppress("ALL") (this::x)).isInitialized
object {
fun local() {
class Local {
val xx = this@Foo::x.isInitialized
val yy = this@Foo::y.isInitialized
}
}
}
}
fun onLiteral() {
val p = this::x
p.isInitialized
}
fun onNonLateinit() {
this::nonLateInit.isInitialized
}
inline fun inlineFun() {
this::x.isInitialized
object {
val z = this@Foo::x.isInitialized
}
}
inner class InnerSubclass : Foo() {
fun innerOk() {
// This is access to Foo.x declared lexically above
this@Foo::x.isInitialized
// This is access to InnerSubclass.x which is inherited from Foo.x
this::x.isInitialized
}
}
}
fun onNonAccessible() {
Foo()::x.isInitialized
}
fun onNonLateinit() {
Foo()::nonLateInit.isInitialized
}
object Unrelated {
fun onNonAccessible() {
Foo()::x.isInitialized
}
}
class FooImpl : Foo() {
fun onNonAccessible() {
this::x.isInitialized
}
}
// FILE: other.kt
class OtherFooImpl : Foo() {
fun onNonAccessible() {
this::x.isInitialized
}
}
@@ -0,0 +1,106 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -NOTHING_TO_INLINE
// !LANGUAGE: -NativeJsProhibitLateinitIsInitalizedIntrinsicWithoutPrivateAccess
// FILE: stdlibInternal.kt
package kotlin.internal
@Target(AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.BINARY)
internal annotation class AccessibleLateinitPropertyLiteral
// FILE: stdlib.kt
package kotlin
import kotlin.internal.AccessibleLateinitPropertyLiteral
import kotlin.reflect.KProperty0
inline val @receiver:AccessibleLateinitPropertyLiteral KProperty0<*>.isInitialized: Boolean
get() = true
// FILE: test.kt
interface Base {
var x: String
}
open class Foo : Base {
override lateinit var x: String
private lateinit var y: String
var nonLateInit: Int = 1
fun ok() {
val b: Boolean = this::x.isInitialized
val otherInstance = Foo()
otherInstance::x.isInitialized
(this::x).isInitialized
(@Suppress("ALL") (this::x)).isInitialized
object {
fun local() {
class Local {
val xx = this@Foo::x.isInitialized
val yy = this@Foo::y.isInitialized
}
}
}
}
fun onLiteral() {
val p = this::x
p.<!LATEINIT_INTRINSIC_CALL_ON_NON_LITERAL_WARNING!>isInitialized<!>
}
fun onNonLateinit() {
this::nonLateInit.<!LATEINIT_INTRINSIC_CALL_ON_NON_LATEINIT_WARNING!>isInitialized<!>
}
inline fun inlineFun() {
this::x.<!LATEINIT_INTRINSIC_CALL_IN_INLINE_FUNCTION_WARNING!>isInitialized<!>
object {
val z = this@Foo::x.isInitialized
}
}
inner class InnerSubclass : Foo() {
fun innerOk() {
// This is access to Foo.x declared lexically above
this@Foo::x.isInitialized
// This is access to InnerSubclass.x which is inherited from Foo.x
this::x.isInitialized
}
}
}
fun onNonAccessible() {
Foo()::x.<!LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY_WARNING!>isInitialized<!>
}
fun onNonLateinit() {
Foo()::nonLateInit.<!LATEINIT_INTRINSIC_CALL_ON_NON_LATEINIT_WARNING!>isInitialized<!>
}
object Unrelated {
fun onNonAccessible() {
Foo()::x.<!LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY_WARNING!>isInitialized<!>
}
}
class FooImpl : Foo() {
fun onNonAccessible() {
this::x.<!LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY_WARNING!>isInitialized<!>
}
}
// FILE: other.kt
class OtherFooImpl : Foo() {
fun onNonAccessible() {
this::x.<!LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY_WARNING!>isInitialized<!>
}
}
@@ -0,0 +1,92 @@
package
public fun onNonAccessible(): kotlin.Unit
public fun onNonLateinit(): kotlin.Unit
public interface Base {
public abstract var x: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class Foo : Base {
public constructor Foo()
public final var nonLateInit: kotlin.Int
public open override /*1*/ lateinit var x: kotlin.String
private final lateinit var y: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final inline fun inlineFun(): kotlin.Unit
public final fun ok(): kotlin.Unit
public final fun onLiteral(): kotlin.Unit
public final fun onNonLateinit(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final inner class InnerSubclass : Foo {
public constructor InnerSubclass()
public final override /*1*/ /*fake_override*/ var nonLateInit: kotlin.Int
public open override /*1*/ lateinit /*fake_override*/ var x: kotlin.String
invisible_fake final override /*1*/ lateinit /*fake_override*/ var y: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ inline /*fake_override*/ fun inlineFun(): kotlin.Unit
public final fun innerOk(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun ok(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onLiteral(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onNonLateinit(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public final class FooImpl : Foo {
public constructor FooImpl()
public final override /*1*/ /*fake_override*/ var nonLateInit: kotlin.Int
public open override /*1*/ lateinit /*fake_override*/ var x: kotlin.String
invisible_fake final override /*1*/ lateinit /*fake_override*/ var y: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ inline /*fake_override*/ fun inlineFun(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun ok(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onLiteral(): kotlin.Unit
public final fun onNonAccessible(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onNonLateinit(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class OtherFooImpl : Foo {
public constructor OtherFooImpl()
public final override /*1*/ /*fake_override*/ var nonLateInit: kotlin.Int
public open override /*1*/ lateinit /*fake_override*/ var x: kotlin.String
invisible_fake final override /*1*/ lateinit /*fake_override*/ var y: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ inline /*fake_override*/ fun inlineFun(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun ok(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onLiteral(): kotlin.Unit
public final fun onNonAccessible(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onNonLateinit(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public object Unrelated {
private constructor Unrelated()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun onNonAccessible(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
package kotlin {
public val @receiver:kotlin.internal.AccessibleLateinitPropertyLiteral kotlin.reflect.KProperty0<*>.isInitialized: kotlin.Boolean
package kotlin.internal {
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.VALUE_PARAMETER}) @kotlin.annotation.Retention(value = AnnotationRetention.BINARY) internal final annotation class AccessibleLateinitPropertyLiteral : kotlin.Annotation {
public constructor AccessibleLateinitPropertyLiteral()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
}
@@ -0,0 +1,106 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -NOTHING_TO_INLINE
// !LANGUAGE: -NativeJsProhibitLateinitIsInitalizedIntrinsicWithoutPrivateAccess
// FILE: stdlibInternal.kt
package kotlin.internal
@Target(AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.BINARY)
internal annotation class AccessibleLateinitPropertyLiteral
// FILE: stdlib.kt
package kotlin
import kotlin.internal.AccessibleLateinitPropertyLiteral
import kotlin.reflect.KProperty0
inline val @receiver:AccessibleLateinitPropertyLiteral KProperty0<*>.isInitialized: Boolean
get() = true
// FILE: test.kt
interface Base {
var x: String
}
open class Foo : Base {
override lateinit var x: String
private lateinit var y: String
var nonLateInit: Int = 1
fun ok() {
val b: Boolean = this::x.isInitialized
val otherInstance = Foo()
otherInstance::x.isInitialized
(this::x).isInitialized
(@Suppress("ALL") (this::x)).isInitialized
object {
fun local() {
class Local {
val xx = this@Foo::x.isInitialized
val yy = this@Foo::y.isInitialized
}
}
}
}
fun onLiteral() {
val p = this::x
p.isInitialized
}
fun onNonLateinit() {
this::nonLateInit.isInitialized
}
inline fun inlineFun() {
this::x.isInitialized
object {
val z = this@Foo::x.isInitialized
}
}
inner class InnerSubclass : Foo() {
fun innerOk() {
// This is access to Foo.x declared lexically above
this@Foo::x.isInitialized
// This is access to InnerSubclass.x which is inherited from Foo.x
this::x.isInitialized
}
}
}
fun onNonAccessible() {
Foo()::x.isInitialized
}
fun onNonLateinit() {
Foo()::nonLateInit.isInitialized
}
object Unrelated {
fun onNonAccessible() {
Foo()::x.isInitialized
}
}
class FooImpl : Foo() {
fun onNonAccessible() {
this::x.isInitialized
}
}
// FILE: other.kt
class OtherFooImpl : Foo() {
fun onNonAccessible() {
this::x.isInitialized
}
}
@@ -0,0 +1,106 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -NOTHING_TO_INLINE
// !LANGUAGE: +NativeJsProhibitLateinitIsInitalizedIntrinsicWithoutPrivateAccess
// FILE: stdlibInternal.kt
package kotlin.internal
@Target(AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.BINARY)
internal annotation class AccessibleLateinitPropertyLiteral
// FILE: stdlib.kt
package kotlin
import kotlin.internal.AccessibleLateinitPropertyLiteral
import kotlin.reflect.KProperty0
inline val @receiver:AccessibleLateinitPropertyLiteral KProperty0<*>.isInitialized: Boolean
get() = true
// FILE: test.kt
interface Base {
var x: String
}
open class Foo : Base {
override lateinit var x: String
private lateinit var y: String
var nonLateInit: Int = 1
fun ok() {
val b: Boolean = this::x.isInitialized
val otherInstance = Foo()
otherInstance::x.isInitialized
(this::x).isInitialized
(@Suppress("ALL") (this::x)).isInitialized
object {
fun local() {
class Local {
val xx = this@Foo::x.isInitialized
val yy = this@Foo::y.isInitialized
}
}
}
}
fun onLiteral() {
val p = this::x
p.<!LATEINIT_INTRINSIC_CALL_ON_NON_LITERAL!>isInitialized<!>
}
fun onNonLateinit() {
this::nonLateInit.<!LATEINIT_INTRINSIC_CALL_ON_NON_LATEINIT!>isInitialized<!>
}
inline fun inlineFun() {
this::x.<!LATEINIT_INTRINSIC_CALL_IN_INLINE_FUNCTION!>isInitialized<!>
object {
val z = this@Foo::x.isInitialized
}
}
inner class InnerSubclass : Foo() {
fun innerOk() {
// This is access to Foo.x declared lexically above
this@Foo::x.isInitialized
// This is access to InnerSubclass.x which is inherited from Foo.x
this::x.isInitialized
}
}
}
fun onNonAccessible() {
Foo()::x.<!LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY!>isInitialized<!>
}
fun onNonLateinit() {
Foo()::nonLateInit.<!LATEINIT_INTRINSIC_CALL_ON_NON_LATEINIT!>isInitialized<!>
}
object Unrelated {
fun onNonAccessible() {
Foo()::x.<!LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY!>isInitialized<!>
}
}
class FooImpl : Foo() {
fun onNonAccessible() {
this::x.<!LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY!>isInitialized<!>
}
}
// FILE: other.kt
class OtherFooImpl : Foo() {
fun onNonAccessible() {
this::x.<!LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY!>isInitialized<!>
}
}
@@ -0,0 +1,92 @@
package
public fun onNonAccessible(): kotlin.Unit
public fun onNonLateinit(): kotlin.Unit
public interface Base {
public abstract var x: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class Foo : Base {
public constructor Foo()
public final var nonLateInit: kotlin.Int
public open override /*1*/ lateinit var x: kotlin.String
private final lateinit var y: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final inline fun inlineFun(): kotlin.Unit
public final fun ok(): kotlin.Unit
public final fun onLiteral(): kotlin.Unit
public final fun onNonLateinit(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final inner class InnerSubclass : Foo {
public constructor InnerSubclass()
public final override /*1*/ /*fake_override*/ var nonLateInit: kotlin.Int
public open override /*1*/ lateinit /*fake_override*/ var x: kotlin.String
invisible_fake final override /*1*/ lateinit /*fake_override*/ var y: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ inline /*fake_override*/ fun inlineFun(): kotlin.Unit
public final fun innerOk(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun ok(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onLiteral(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onNonLateinit(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public final class FooImpl : Foo {
public constructor FooImpl()
public final override /*1*/ /*fake_override*/ var nonLateInit: kotlin.Int
public open override /*1*/ lateinit /*fake_override*/ var x: kotlin.String
invisible_fake final override /*1*/ lateinit /*fake_override*/ var y: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ inline /*fake_override*/ fun inlineFun(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun ok(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onLiteral(): kotlin.Unit
public final fun onNonAccessible(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onNonLateinit(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class OtherFooImpl : Foo {
public constructor OtherFooImpl()
public final override /*1*/ /*fake_override*/ var nonLateInit: kotlin.Int
public open override /*1*/ lateinit /*fake_override*/ var x: kotlin.String
invisible_fake final override /*1*/ lateinit /*fake_override*/ var y: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final override /*1*/ inline /*fake_override*/ fun inlineFun(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun ok(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onLiteral(): kotlin.Unit
public final fun onNonAccessible(): kotlin.Unit
public final override /*1*/ /*fake_override*/ fun onNonLateinit(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public object Unrelated {
private constructor Unrelated()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun onNonAccessible(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
package kotlin {
public val @receiver:kotlin.internal.AccessibleLateinitPropertyLiteral kotlin.reflect.KProperty0<*>.isInitialized: kotlin.Boolean
package kotlin.internal {
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.VALUE_PARAMETER}) @kotlin.annotation.Retention(value = AnnotationRetention.BINARY) internal final annotation class AccessibleLateinitPropertyLiteral : kotlin.Annotation {
public constructor AccessibleLateinitPropertyLiteral()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
}
@@ -30,6 +30,18 @@ public class DiagnosticsNativeTestGenerated extends AbstractDiagnosticsNativeTes
runTest("compiler/testData/diagnostics/nativeTests/identifiers.kt");
}
@Test
@TestMetadata("isInitialized.kt")
public void testIsInitialized() throws Exception {
runTest("compiler/testData/diagnostics/nativeTests/isInitialized.kt");
}
@Test
@TestMetadata("isInitializedError.kt")
public void testIsInitializedError() throws Exception {
runTest("compiler/testData/diagnostics/nativeTests/isInitializedError.kt");
}
@Test
@TestMetadata("objCName.kt")
public void testObjCName() throws Exception {
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.classicFrontendHandlersStep
import org.jetbrains.kotlin.test.builders.firHandlersStep
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives
@@ -59,6 +60,12 @@ abstract class AbstractDiagnosticsNativeTestBase<R : ResultingArtifact.FrontendO
forTestsMatching("testData/diagnostics/nativeTests/*") {
defaultDirectives {
+LanguageSettingsDirectives.ALLOW_KOTLIN_PACKAGE
+ConfigurationDirectives.WITH_STDLIB
}
}
forTestsMatching("testData/diagnostics/nativeTests/testsWithStdLib/*") {
defaultDirectives {
+ConfigurationDirectives.WITH_STDLIB
}
}
}
@@ -280,6 +280,7 @@ enum class LanguageFeature(
RefineTypeCheckingOnAssignmentsToJavaFields(KOTLIN_1_9, kind = BUG_FIX), // KT-46727
ReferencesToSyntheticJavaProperties(KOTLIN_1_9), // KT-8575
ValueClassesSecondaryConstructorWithBody(sinceVersion = KOTLIN_1_9, kind = UNSTABLE_FEATURE), // KT-55333
NativeJsProhibitLateinitIsInitalizedIntrinsicWithoutPrivateAccess(KOTLIN_1_9, kind = BUG_FIX), // KT-27002
// This feature effectively might be removed because we decided to disable it until K2 and there it will be unconditionally enabled.
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.js.analyze.JsNativeDiagnosticSuppressor
import org.jetbrains.kotlin.js.naming.NameSuggestion
import org.jetbrains.kotlin.js.resolve.diagnostics.*
import org.jetbrains.kotlin.resolve.PlatformConfiguratorBase
import org.jetbrains.kotlin.resolve.calls.checkers.LateinitIntrinsicApplicabilityChecker
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.types.DynamicTypesAllowed
@@ -30,6 +31,7 @@ object JsPlatformConfigurator : PlatformConfiguratorBase(
JsModuleCallChecker,
JsDynamicCallChecker,
JsDefinedExternallyCallChecker,
LateinitIntrinsicApplicabilityChecker(isWarningInPre19 = true)
),
) {
override fun configureModuleComponents(container: StorageComponentContainer) {
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.PlatformConfiguratorBase
import org.jetbrains.kotlin.resolve.calls.checkers.LateinitIntrinsicApplicabilityChecker
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.resolve.inline.ReasonableInlineRule
import org.jetbrains.kotlin.resolve.jvm.checkers.SuperCallWithDefaultArgumentsChecker
@@ -20,6 +21,7 @@ import org.jetbrains.kotlin.resolve.konan.diagnostics.*
object NativePlatformConfigurator : PlatformConfiguratorBase(
additionalCallCheckers = listOf(
SuperCallWithDefaultArgumentsChecker(),
LateinitIntrinsicApplicabilityChecker(isWarningInPre19 = true)
),
additionalDeclarationCheckers = listOf(
NativeThrowsChecker, NativeSharedImmutableChecker,