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:
committed by
Space Team
parent
17e9a6a781
commit
4928e284f6
+12
@@ -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 {
|
||||
|
||||
+12
@@ -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 {
|
||||
|
||||
+2
@@ -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);
|
||||
|
||||
|
||||
+4
@@ -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,
|
||||
|
||||
+21
-5
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -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 {
|
||||
|
||||
+7
@@ -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) {
|
||||
|
||||
+2
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user