FIR: add smartcast stability to FIR
This commit is contained in:
committed by
Dmitriy Novozhilov
parent
931a637bdd
commit
96bd2c54f0
+5
-1
@@ -274,7 +274,11 @@ class Fir2IrImplicitCastInserter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitExpressionWithSmartcast(expressionWithSmartcast: FirExpressionWithSmartcast, data: IrElement): IrExpression {
|
override fun visitExpressionWithSmartcast(expressionWithSmartcast: FirExpressionWithSmartcast, data: IrElement): IrExpression {
|
||||||
return implicitCastOrExpression(data as IrExpression, expressionWithSmartcast.typeRef)
|
return if (expressionWithSmartcast.smartcastStability == SmartcastStability.STABLE_VALUE) {
|
||||||
|
implicitCastOrExpression(data as IrExpression, expressionWithSmartcast.typeRef)
|
||||||
|
} else {
|
||||||
|
data as IrExpression
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitExpressionWithSmartcastToNull(
|
override fun visitExpressionWithSmartcastToNull(
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
|||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||||
import org.jetbrains.kotlin.name.*
|
import org.jetbrains.kotlin.name.*
|
||||||
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
||||||
|
import org.jetbrains.kotlin.types.SmartcastStability
|
||||||
|
|
||||||
fun List<FirQualifierPart>.toTypeProjections(): Array<ConeTypeProjection> =
|
fun List<FirQualifierPart>.toTypeProjections(): Array<ConeTypeProjection> =
|
||||||
asReversed().flatMap { it.typeArgumentList.typeArguments.map { typeArgument -> typeArgument.toConeTypeProjection() } }.toTypedArray()
|
asReversed().flatMap { it.typeArgumentList.typeArguments.map { typeArgument -> typeArgument.toConeTypeProjection() } }.toTypedArray()
|
||||||
@@ -285,8 +286,9 @@ fun BodyResolveComponents.transformQualifiedAccessUsingSmartcastInfo(
|
|||||||
}
|
}
|
||||||
return buildExpressionWithSmartcast {
|
return buildExpressionWithSmartcast {
|
||||||
originalExpression = qualifiedAccessExpression
|
originalExpression = qualifiedAccessExpression
|
||||||
typeRef = intersectedTypeRef
|
smartcastType = intersectedTypeRef
|
||||||
this.typesFromSmartCast = typesFromSmartCast
|
this.typesFromSmartCast = typesFromSmartCast
|
||||||
|
smartcastStability = SmartcastStability.STABLE_VALUE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
|||||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
|
import org.jetbrains.kotlin.types.SmartcastStability
|
||||||
|
|
||||||
interface Receiver
|
interface Receiver
|
||||||
|
|
||||||
@@ -89,8 +90,9 @@ sealed class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>(
|
|||||||
} else {
|
} else {
|
||||||
buildExpressionWithSmartcast {
|
buildExpressionWithSmartcast {
|
||||||
originalExpression = originalReceiverExpression
|
originalExpression = originalReceiverExpression
|
||||||
typeRef = originalReceiverExpression.typeRef.resolvedTypeFromPrototype(type)
|
smartcastType = originalReceiverExpression.typeRef.resolvedTypeFromPrototype(type)
|
||||||
typesFromSmartCast = listOf(type)
|
typesFromSmartCast = listOf(type)
|
||||||
|
smartcastStability = SmartcastStability.STABLE_VALUE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
implicitScope = type.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
implicitScope = type.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||||
|
|||||||
+3
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.references.FirReference
|
|||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
|
import org.jetbrains.kotlin.types.SmartcastStability
|
||||||
import org.jetbrains.kotlin.fir.visitors.*
|
import org.jetbrains.kotlin.fir.visitors.*
|
||||||
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
||||||
|
|
||||||
@@ -31,6 +32,8 @@ abstract class FirExpressionWithSmartcast : FirQualifiedAccessExpression() {
|
|||||||
abstract val originalExpression: FirQualifiedAccessExpression
|
abstract val originalExpression: FirQualifiedAccessExpression
|
||||||
abstract val typesFromSmartCast: Collection<ConeKotlinType>
|
abstract val typesFromSmartCast: Collection<ConeKotlinType>
|
||||||
abstract val originalType: FirTypeRef
|
abstract val originalType: FirTypeRef
|
||||||
|
abstract val smartcastType: FirTypeRef
|
||||||
|
abstract val smartcastStability: SmartcastStability
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitExpressionWithSmartcast(this, data)
|
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitExpressionWithSmartcast(this, data)
|
||||||
|
|
||||||
|
|||||||
+3
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.references.FirReference
|
|||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
|
import org.jetbrains.kotlin.types.SmartcastStability
|
||||||
import org.jetbrains.kotlin.fir.visitors.*
|
import org.jetbrains.kotlin.fir.visitors.*
|
||||||
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
||||||
|
|
||||||
@@ -31,6 +32,8 @@ abstract class FirExpressionWithSmartcastToNull : FirExpressionWithSmartcast() {
|
|||||||
abstract override val originalExpression: FirQualifiedAccessExpression
|
abstract override val originalExpression: FirQualifiedAccessExpression
|
||||||
abstract override val typesFromSmartCast: Collection<ConeKotlinType>
|
abstract override val typesFromSmartCast: Collection<ConeKotlinType>
|
||||||
abstract override val originalType: FirTypeRef
|
abstract override val originalType: FirTypeRef
|
||||||
|
abstract override val smartcastType: FirTypeRef
|
||||||
|
abstract override val smartcastStability: SmartcastStability
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitExpressionWithSmartcastToNull(this, data)
|
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitExpressionWithSmartcastToNull(this, data)
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -10,14 +10,16 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
|||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionWithSmartcastImpl
|
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionWithSmartcastImpl
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
|
import org.jetbrains.kotlin.types.SmartcastStability
|
||||||
|
|
||||||
class FirExpressionWithSmartcastBuilder {
|
class FirExpressionWithSmartcastBuilder {
|
||||||
lateinit var originalExpression: FirQualifiedAccessExpression
|
lateinit var originalExpression: FirQualifiedAccessExpression
|
||||||
lateinit var typeRef: FirTypeRef
|
lateinit var smartcastType: FirTypeRef
|
||||||
lateinit var typesFromSmartCast: Collection<ConeKotlinType>
|
lateinit var typesFromSmartCast: Collection<ConeKotlinType>
|
||||||
|
lateinit var smartcastStability: SmartcastStability
|
||||||
|
|
||||||
fun build(): FirExpressionWithSmartcast {
|
fun build(): FirExpressionWithSmartcast {
|
||||||
return FirExpressionWithSmartcastImpl(originalExpression, typeRef, typesFromSmartCast)
|
return FirExpressionWithSmartcastImpl(originalExpression, smartcastType, typesFromSmartCast, smartcastStability)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -10,14 +10,16 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
|||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionWithSmartcastToNullImpl
|
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionWithSmartcastToNullImpl
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
|
import org.jetbrains.kotlin.types.SmartcastStability
|
||||||
|
|
||||||
class FirExpressionWithSmartcastToNullBuilder {
|
class FirExpressionWithSmartcastToNullBuilder {
|
||||||
lateinit var originalExpression: FirQualifiedAccessExpression
|
lateinit var originalExpression: FirQualifiedAccessExpression
|
||||||
lateinit var typeRef: FirTypeRef
|
lateinit var smartcastType: FirTypeRef
|
||||||
lateinit var typesFromSmartCast: Collection<ConeKotlinType>
|
lateinit var typesFromSmartCast: Collection<ConeKotlinType>
|
||||||
|
lateinit var smartcastStability: SmartcastStability
|
||||||
|
|
||||||
fun build(): FirExpressionWithSmartcastToNull {
|
fun build(): FirExpressionWithSmartcastToNull {
|
||||||
return FirExpressionWithSmartcastToNullImpl(originalExpression, typeRef, typesFromSmartCast)
|
return FirExpressionWithSmartcastToNullImpl(originalExpression, smartcastType, typesFromSmartCast, smartcastStability)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-2
@@ -19,11 +19,13 @@ import org.jetbrains.kotlin.fir.types.FirTypeRef
|
|||||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||||
|
import org.jetbrains.kotlin.types.SmartcastStability
|
||||||
|
|
||||||
internal class FirExpressionWithSmartcastImpl(
|
internal class FirExpressionWithSmartcastImpl(
|
||||||
override var originalExpression: FirQualifiedAccessExpression,
|
override var originalExpression: FirQualifiedAccessExpression,
|
||||||
override val typeRef: FirTypeRef,
|
override val smartcastType: FirTypeRef,
|
||||||
override val typesFromSmartCast: Collection<ConeKotlinType>
|
override val typesFromSmartCast: Collection<ConeKotlinType>,
|
||||||
|
override val smartcastStability: SmartcastStability
|
||||||
) : FirExpressionWithSmartcast() {
|
) : FirExpressionWithSmartcast() {
|
||||||
init {
|
init {
|
||||||
assert(originalExpression.typeRef is FirResolvedTypeRef)
|
assert(originalExpression.typeRef is FirResolvedTypeRef)
|
||||||
@@ -37,6 +39,10 @@ internal class FirExpressionWithSmartcastImpl(
|
|||||||
override val extensionReceiver: FirExpression get() = originalExpression.extensionReceiver
|
override val extensionReceiver: FirExpression get() = originalExpression.extensionReceiver
|
||||||
override val calleeReference: FirReference get() = originalExpression.calleeReference
|
override val calleeReference: FirReference get() = originalExpression.calleeReference
|
||||||
override val originalType: FirTypeRef get() = originalExpression.typeRef
|
override val originalType: FirTypeRef get() = originalExpression.typeRef
|
||||||
|
// A FirExpressionWithSmartcast is only an effective smartcast if `smartcastStability == SmartcastStability.STABLE_VALUE`. Otherwise,
|
||||||
|
// it's the same as the `originalExpression` under the hood. The reason we still create such a smartcast expression is for diagnostics
|
||||||
|
// purpose only.
|
||||||
|
override val typeRef: FirTypeRef get() = if (smartcastStability == SmartcastStability.STABLE_VALUE) smartcastType else originalType
|
||||||
|
|
||||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirExpressionWithSmartcast {
|
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirExpressionWithSmartcast {
|
||||||
originalExpression = originalExpression.transformSingle(transformer, data)
|
originalExpression = originalExpression.transformSingle(transformer, data)
|
||||||
|
|||||||
+8
-2
@@ -16,11 +16,13 @@ import org.jetbrains.kotlin.fir.types.FirTypeRef
|
|||||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||||
|
import org.jetbrains.kotlin.types.SmartcastStability
|
||||||
|
|
||||||
class FirExpressionWithSmartcastToNullImpl(
|
class FirExpressionWithSmartcastToNullImpl(
|
||||||
override var originalExpression: FirQualifiedAccessExpression,
|
override var originalExpression: FirQualifiedAccessExpression,
|
||||||
override val typeRef: FirTypeRef,
|
override val smartcastType: FirTypeRef,
|
||||||
override val typesFromSmartCast: Collection<ConeKotlinType>
|
override val typesFromSmartCast: Collection<ConeKotlinType>,
|
||||||
|
override val smartcastStability: SmartcastStability
|
||||||
) : FirExpressionWithSmartcastToNull() {
|
) : FirExpressionWithSmartcastToNull() {
|
||||||
init {
|
init {
|
||||||
assert(originalExpression.typeRef is FirResolvedTypeRef)
|
assert(originalExpression.typeRef is FirResolvedTypeRef)
|
||||||
@@ -34,6 +36,10 @@ class FirExpressionWithSmartcastToNullImpl(
|
|||||||
override val extensionReceiver: FirExpression get() = originalExpression.extensionReceiver
|
override val extensionReceiver: FirExpression get() = originalExpression.extensionReceiver
|
||||||
override val calleeReference: FirReference get() = originalExpression.calleeReference
|
override val calleeReference: FirReference get() = originalExpression.calleeReference
|
||||||
override val originalType: FirTypeRef get() = originalExpression.typeRef
|
override val originalType: FirTypeRef get() = originalExpression.typeRef
|
||||||
|
// A FirExpressionWithSmartcast is only an effective smartcast if `smartcastStability == SmartcastStability.STABLE_VALUE`. Otherwise,
|
||||||
|
// it's the same as the `originalExpression` under the hood. The reason we still create such a smartcast expression is for diagnostics
|
||||||
|
// purpose only.
|
||||||
|
override val typeRef: FirTypeRef get() = if (smartcastStability == SmartcastStability.STABLE_VALUE) smartcastType else originalType
|
||||||
|
|
||||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirExpressionWithSmartcastToNull {
|
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirExpressionWithSmartcastToNull {
|
||||||
originalExpression = originalExpression.transformSingle(transformer, data)
|
originalExpression = originalExpression.transformSingle(transformer, data)
|
||||||
|
|||||||
+2
@@ -83,4 +83,6 @@ object FieldSets {
|
|||||||
val modality = field(modalityType, nullable = true)
|
val modality = field(modalityType, nullable = true)
|
||||||
|
|
||||||
val scopeProvider = field("scopeProvider", firScopeProviderType)
|
val scopeProvider = field("scopeProvider", firScopeProviderType)
|
||||||
|
|
||||||
|
val smartcastStability = field(smartcastStabilityType)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.tree.generator.FieldSets.name
|
|||||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.receivers
|
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.receivers
|
||||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.returnTypeRef
|
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.returnTypeRef
|
||||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.scopeProvider
|
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.scopeProvider
|
||||||
|
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.smartcastStability
|
||||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.status
|
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.status
|
||||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.superTypeRefs
|
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.superTypeRefs
|
||||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.symbol
|
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.symbol
|
||||||
@@ -458,6 +459,8 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
|||||||
+field("originalExpression", qualifiedAccessExpression)
|
+field("originalExpression", qualifiedAccessExpression)
|
||||||
+field("typesFromSmartCast", "Collection<ConeKotlinType>", null, customType = coneKotlinTypeType)
|
+field("typesFromSmartCast", "Collection<ConeKotlinType>", null, customType = coneKotlinTypeType)
|
||||||
+field("originalType", typeRef)
|
+field("originalType", typeRef)
|
||||||
|
+field("smartcastType", typeRef)
|
||||||
|
+smartcastStability
|
||||||
}
|
}
|
||||||
|
|
||||||
expressionWithSmartcastToNull.configure {
|
expressionWithSmartcastToNull.configure {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
|||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.types.SmartcastStability
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
val sourceElementType = type("fir", "FirSourceElement")
|
val sourceElementType = type("fir", "FirSourceElement")
|
||||||
@@ -31,6 +32,7 @@ val nameType = type(Name::class)
|
|||||||
val visibilityType = type(Visibility::class)
|
val visibilityType = type(Visibility::class)
|
||||||
val effectiveVisibilityType = type("descriptors", "EffectiveVisibility")
|
val effectiveVisibilityType = type("descriptors", "EffectiveVisibility")
|
||||||
val modalityType = type(Modality::class)
|
val modalityType = type(Modality::class)
|
||||||
|
val smartcastStabilityType = type(SmartcastStability::class)
|
||||||
val fqNameType = type(FqName::class)
|
val fqNameType = type(FqName::class)
|
||||||
val classIdType = type(ClassId::class)
|
val classIdType = type(ClassId::class)
|
||||||
val annotationUseSiteTargetType = type(AnnotationUseSiteTarget::class)
|
val annotationUseSiteTargetType = type(AnnotationUseSiteTarget::class)
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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.types
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See https://kotlinlang.org/spec/type-inference.html#smart-cast-sink-stability for explanation on smartcast stability. The "mutable value
|
||||||
|
* capturing" and "concurrent writes" categories in the spec are covered by [CAPTURED_VARIABLE] and [MUTABLE_PROPERTY] together.
|
||||||
|
* Specifically, we only do capture analysis on local mutable properties. Non-local ones are considered to be always unstable (assuming
|
||||||
|
* some concurrent writes are always present).
|
||||||
|
*/
|
||||||
|
enum class SmartcastStability(private val str: String, val description: String = str) {
|
||||||
|
// Local value, or parameter, or private / internal member value without open / custom getter,
|
||||||
|
// or protected / public member value from the same module without open / custom getter
|
||||||
|
// Smart casts are completely safe
|
||||||
|
STABLE_VALUE("stable val"),
|
||||||
|
|
||||||
|
// Member value with open / custom getter
|
||||||
|
// Smart casts are not safe
|
||||||
|
PROPERTY_WITH_GETTER("custom getter", "property that has open or custom getter"),
|
||||||
|
|
||||||
|
// Protected / public member value from another module
|
||||||
|
// Smart casts are not safe
|
||||||
|
ALIEN_PUBLIC_PROPERTY("alien public", "public API property declared in different module"),
|
||||||
|
|
||||||
|
// Local variable already captured by a changing closure
|
||||||
|
// Smart casts are not safe
|
||||||
|
CAPTURED_VARIABLE("captured var", "local variable that is captured by a changing closure"),
|
||||||
|
|
||||||
|
// Member variable regardless of its visibility
|
||||||
|
// Smart casts are not safe
|
||||||
|
MUTABLE_PROPERTY("member", "mutable property that could have been changed by this time"),
|
||||||
|
|
||||||
|
// A delegated property.
|
||||||
|
// Smart casts are not safe
|
||||||
|
DELEGATED_PROPERTY("delegate", "delegated property that could have been changed by this time"),
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user