[FIR] Fix false positive CONST_VAL_WITH_NON_CONST_INITIALIZER
... in presence of typealiases. #KT-61499 Fixed
This commit is contained in:
committed by
Space Team
parent
b72ac4f560
commit
373ffbc779
+10
-10
@@ -90,7 +90,7 @@ internal fun checkConstantArguments(
|
|||||||
if (coneType is ConeErrorType)
|
if (coneType is ConeErrorType)
|
||||||
return ConstantArgumentKind.NOT_CONST
|
return ConstantArgumentKind.NOT_CONST
|
||||||
|
|
||||||
while (coneType?.classId == StandardClassIds.Array)
|
while (coneType?.fullyExpandedClassId(session) == StandardClassIds.Array)
|
||||||
coneType = (coneType.lowerBoundIfFlexible().typeArguments.first() as? ConeKotlinTypeProjection)?.type ?: break
|
coneType = (coneType.lowerBoundIfFlexible().typeArguments.first() as? ConeKotlinTypeProjection)?.type ?: break
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
@@ -122,7 +122,7 @@ internal fun checkConstantArguments(
|
|||||||
if (calleeReference is FirErrorNamedReference) {
|
if (calleeReference is FirErrorNamedReference) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
if (expression.resolvedType.classId == StandardClassIds.KClass) {
|
if (expression.resolvedType.fullyExpandedClassId(session) == StandardClassIds.KClass) {
|
||||||
return ConstantArgumentKind.NOT_KCLASS_LITERAL
|
return ConstantArgumentKind.NOT_KCLASS_LITERAL
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,13 +134,13 @@ internal fun checkConstantArguments(
|
|||||||
if (calleeReference !is FirResolvedNamedReference) return ConstantArgumentKind.NOT_CONST
|
if (calleeReference !is FirResolvedNamedReference) return ConstantArgumentKind.NOT_CONST
|
||||||
val symbol = calleeReference.resolvedSymbol as? FirNamedFunctionSymbol ?: return ConstantArgumentKind.NOT_CONST
|
val symbol = calleeReference.resolvedSymbol as? FirNamedFunctionSymbol ?: return ConstantArgumentKind.NOT_CONST
|
||||||
|
|
||||||
if (!symbol.canBeEvaluated() && !expression.isCompileTimeBuiltinCall() || expression.isForbiddenComplexConstant(session)) {
|
if (!symbol.canBeEvaluated() && !expression.isCompileTimeBuiltinCall(session) || expression.isForbiddenComplexConstant(session)) {
|
||||||
return ConstantArgumentKind.NOT_CONST
|
return ConstantArgumentKind.NOT_CONST
|
||||||
}
|
}
|
||||||
|
|
||||||
for (exp in expression.arguments.plus(expression.dispatchReceiver).plus(expression.extensionReceiver)) {
|
for (exp in expression.arguments.plus(expression.dispatchReceiver).plus(expression.extensionReceiver)) {
|
||||||
if (exp == null) continue
|
if (exp == null) continue
|
||||||
val expClassId = exp.resolvedType.lowerBoundIfFlexible().classId
|
val expClassId = exp.resolvedType.fullyExpandedClassId(session)
|
||||||
// TODO, KT-59823: add annotation for allowed constant types
|
// TODO, KT-59823: add annotation for allowed constant types
|
||||||
if (expClassId !in StandardClassIds.constantAllowedTypes) {
|
if (expClassId !in StandardClassIds.constantAllowedTypes) {
|
||||||
return ConstantArgumentKind.NOT_CONST
|
return ConstantArgumentKind.NOT_CONST
|
||||||
@@ -165,12 +165,12 @@ internal fun checkConstantArguments(
|
|||||||
@OptIn(SymbolInternals::class)
|
@OptIn(SymbolInternals::class)
|
||||||
val property = propertySymbol.fir
|
val property = propertySymbol.fir
|
||||||
when {
|
when {
|
||||||
property.unwrapFakeOverrides().symbol.canBeEvaluated() || property.isCompileTimeBuiltinProperty() -> {
|
property.unwrapFakeOverrides().symbol.canBeEvaluated() || property.isCompileTimeBuiltinProperty(session) -> {
|
||||||
val receiver = listOf(expression.dispatchReceiver, expression.extensionReceiver).single { it != null }!!
|
val receiver = listOf(expression.dispatchReceiver, expression.extensionReceiver).single { it != null }!!
|
||||||
return checkConstantArguments(receiver, session)
|
return checkConstantArguments(receiver, session)
|
||||||
}
|
}
|
||||||
propertySymbol.isLocal || propertySymbol.callableId.className?.isRoot == false -> return ConstantArgumentKind.NOT_CONST
|
propertySymbol.isLocal || propertySymbol.callableId.className?.isRoot == false -> return ConstantArgumentKind.NOT_CONST
|
||||||
expressionType.classId == StandardClassIds.KClass -> return ConstantArgumentKind.NOT_KCLASS_LITERAL
|
expressionType.fullyExpandedClassId(session) == StandardClassIds.KClass -> return ConstantArgumentKind.NOT_KCLASS_LITERAL
|
||||||
|
|
||||||
//TODO, KT-59822: UNRESOLVED REFERENCE
|
//TODO, KT-59822: UNRESOLVED REFERENCE
|
||||||
expression.dispatchReceiver is FirThisReceiverExpression -> return null
|
expression.dispatchReceiver is FirThisReceiverExpression -> return null
|
||||||
@@ -229,7 +229,7 @@ private val compileTimeConversionFunctions = listOf(
|
|||||||
"toInt", "toLong", "toShort", "toByte", "toFloat", "toDouble", "toChar", "toBoolean"
|
"toInt", "toLong", "toShort", "toByte", "toFloat", "toDouble", "toChar", "toBoolean"
|
||||||
).mapTo(hashSetOf()) { Name.identifier(it) }
|
).mapTo(hashSetOf()) { Name.identifier(it) }
|
||||||
|
|
||||||
private fun FirFunctionCall.isCompileTimeBuiltinCall(): Boolean {
|
private fun FirFunctionCall.isCompileTimeBuiltinCall(session: FirSession): Boolean {
|
||||||
val calleeReference = this.calleeReference
|
val calleeReference = this.calleeReference
|
||||||
if (calleeReference !is FirResolvedNamedReference) return false
|
if (calleeReference !is FirResolvedNamedReference) return false
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ private fun FirFunctionCall.isCompileTimeBuiltinCall(): Boolean {
|
|||||||
if (!symbol.fromKotlin()) return false
|
if (!symbol.fromKotlin()) return false
|
||||||
|
|
||||||
val coneType = this.dispatchReceiver?.resolvedType
|
val coneType = this.dispatchReceiver?.resolvedType
|
||||||
val receiverClassId = coneType?.lowerBoundIfFlexible()?.classId
|
val receiverClassId = coneType?.fullyExpandedClassId(session)
|
||||||
|
|
||||||
if (receiverClassId in StandardClassIds.unsignedTypes) return false
|
if (receiverClassId in StandardClassIds.unsignedTypes) return false
|
||||||
|
|
||||||
@@ -254,9 +254,9 @@ private fun FirFunctionCall.isCompileTimeBuiltinCall(): Boolean {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirProperty.isCompileTimeBuiltinProperty(): Boolean {
|
private fun FirProperty.isCompileTimeBuiltinProperty(session: FirSession): Boolean {
|
||||||
val receiverType = dispatchReceiverType ?: receiverParameter?.typeRef?.coneTypeSafe<ConeKotlinType>() ?: return false
|
val receiverType = dispatchReceiverType ?: receiverParameter?.typeRef?.coneTypeSafe<ConeKotlinType>() ?: return false
|
||||||
val receiverClassId = receiverType.lowerBoundIfFlexible().classId ?: return false
|
val receiverClassId = receiverType.fullyExpandedClassId(session) ?: return false
|
||||||
return when (name.asString()) {
|
return when (name.asString()) {
|
||||||
"length" -> receiverClassId == StandardClassIds.String
|
"length" -> receiverClassId == StandardClassIds.String
|
||||||
"code" -> receiverClassId == StandardClassIds.Char
|
"code" -> receiverClassId == StandardClassIds.Char
|
||||||
|
|||||||
@@ -100,6 +100,10 @@ const val constInitializer12 = (-1.0) % 0
|
|||||||
const val constInitializer13 = 1.0.rem(0)
|
const val constInitializer13 = 1.0.rem(0)
|
||||||
const val constInitializer15 = 1.0.div(0)
|
const val constInitializer15 = 1.0.div(0)
|
||||||
|
|
||||||
|
typealias IntAlias = Int
|
||||||
|
const val constInitializer16: IntAlias = 1
|
||||||
|
const val constInitializer17 = constInitializer16 + 0
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
class Delegate {
|
class Delegate {
|
||||||
operator fun getValue(thisRef: Any?, prop: KProperty<*>): Int = 1
|
operator fun getValue(thisRef: Any?, prop: KProperty<*>): Int = 1
|
||||||
|
|||||||
@@ -100,6 +100,10 @@ const val constInitializer12 = (-1.0) % 0
|
|||||||
const val constInitializer13 = 1.0.rem(0)
|
const val constInitializer13 = 1.0.rem(0)
|
||||||
const val constInitializer15 = 1.0.div(0)
|
const val constInitializer15 = 1.0.div(0)
|
||||||
|
|
||||||
|
typealias IntAlias = Int
|
||||||
|
const val constInitializer16: IntAlias = 1
|
||||||
|
const val constInitializer17 = constInitializer16 + 0
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
class Delegate {
|
class Delegate {
|
||||||
operator fun getValue(thisRef: Any?, prop: KProperty<*>): Int = 1
|
operator fun getValue(thisRef: Any?, prop: KProperty<*>): Int = 1
|
||||||
|
|||||||
@@ -1,136 +0,0 @@
|
|||||||
package
|
|
||||||
|
|
||||||
public const val constInitializer1: kotlin.Double = Infinity.toDouble()
|
|
||||||
public const val constInitializer10: kotlin.Double = NaN.toDouble()
|
|
||||||
public const val constInitializer11: kotlin.Double = NaN.toDouble()
|
|
||||||
public const val constInitializer12: kotlin.Double = NaN.toDouble()
|
|
||||||
public const val constInitializer13: kotlin.Double = NaN.toDouble()
|
|
||||||
public const val constInitializer15: kotlin.Double = Infinity.toDouble()
|
|
||||||
public const val constInitializer2: kotlin.Double = Infinity.toDouble()
|
|
||||||
public const val constInitializer3: kotlin.Double = Infinity.toDouble()
|
|
||||||
public const val constInitializer4: kotlin.Double = -Infinity.toDouble()
|
|
||||||
public const val constInitializer5: kotlin.Double = NaN.toDouble()
|
|
||||||
public const val constInitializer6: kotlin.Double = Infinity.toDouble()
|
|
||||||
public const val constInitializer7: kotlin.Double = -Infinity.toDouble()
|
|
||||||
public const val constInitializer8: kotlin.Double = NaN.toDouble()
|
|
||||||
public const val constInitializer9: kotlin.Double = NaN.toDouble()
|
|
||||||
public const val defaultGetter: kotlin.Int = 19
|
|
||||||
public const val delegated: kotlin.Int
|
|
||||||
public const val nonConstInitializer1: kotlin.Int
|
|
||||||
public const val nonConstInitializer10: kotlin.Int
|
|
||||||
public const val nonConstInitializer11: kotlin.Int
|
|
||||||
public const val nonConstInitializer12: kotlin.Int
|
|
||||||
public const val nonConstInitializer14: kotlin.Int
|
|
||||||
public const val nonConstInitializer15: kotlin.Int
|
|
||||||
public const val nonConstInitializer2: kotlin.String
|
|
||||||
public const val nonConstInitializer3: kotlin.String
|
|
||||||
public const val nonConstInitializer4: kotlin.Double
|
|
||||||
public const val nonConstInitializer5: kotlin.Int
|
|
||||||
public const val nonConstInitializer6: kotlin.Int
|
|
||||||
public const val nonConstInitializer7: kotlin.Int
|
|
||||||
public const val nonConstInitializer8: kotlin.Int
|
|
||||||
public const val nonConstInitializer9: kotlin.Double
|
|
||||||
private val privateTopLevel: kotlin.Int = 3
|
|
||||||
public const var topLeveLVar: kotlin.Int
|
|
||||||
public const val topLevel: kotlin.Int = 0
|
|
||||||
public const val topLevelInferred: kotlin.Int = 1
|
|
||||||
public const val withExplicitDefaultGetter: kotlin.Int = 1
|
|
||||||
public const val withGetter: kotlin.Int
|
|
||||||
public fun foo(): kotlin.Int
|
|
||||||
|
|
||||||
public object A {
|
|
||||||
private constructor A()
|
|
||||||
public const final val inObject: kotlin.Int = 4
|
|
||||||
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 final class B {
|
|
||||||
public constructor B(/*0*/ constructor: kotlin.Int = ...)
|
|
||||||
public final val constructor: kotlin.Int
|
|
||||||
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 abstract class C {
|
|
||||||
public constructor C()
|
|
||||||
public const open val x: kotlin.Int = 6
|
|
||||||
public const abstract val y: kotlin.Int = 7
|
|
||||||
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 companion object Companion {
|
|
||||||
private constructor Companion()
|
|
||||||
public const final val inCompaionObject: kotlin.Int = 8
|
|
||||||
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 object D : C {
|
|
||||||
private constructor D()
|
|
||||||
public const final val final: kotlin.Int = 11
|
|
||||||
public const final val inObject: kotlin.Int = 10
|
|
||||||
public const final val withoutInitializer: kotlin.Int
|
|
||||||
public const open override /*1*/ val x: kotlin.Int = 9
|
|
||||||
public const abstract override /*1*/ /*fake_override*/ val y: kotlin.Int = 7
|
|
||||||
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 final class Delegate {
|
|
||||||
public constructor Delegate()
|
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
|
||||||
public final operator fun getValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.reflect.KProperty<*>): kotlin.Int
|
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
|
||||||
public final operator fun setValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.reflect.KProperty<*>, /*2*/ value: kotlin.Int): kotlin.Unit
|
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
|
||||||
}
|
|
||||||
|
|
||||||
public final enum class MyEnum : kotlin.Enum<MyEnum> {
|
|
||||||
enum entry A
|
|
||||||
|
|
||||||
private constructor MyEnum()
|
|
||||||
public const final val inEnum: kotlin.Int = 17
|
|
||||||
@kotlin.internal.IntrinsicConstEvaluation public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
|
||||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
|
||||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
|
||||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: MyEnum): kotlin.Int
|
|
||||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
|
||||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
|
||||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<MyEnum!>!
|
|
||||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
|
||||||
|
|
||||||
// Static members
|
|
||||||
public final /*synthesized*/ val entries: kotlin.enums.EnumEntries<MyEnum>
|
|
||||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): MyEnum
|
|
||||||
public final /*synthesized*/ fun values(): kotlin.Array<MyEnum>
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class Outer {
|
|
||||||
public constructor Outer()
|
|
||||||
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 final inner class Inner {
|
|
||||||
public constructor Inner()
|
|
||||||
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 object C {
|
|
||||||
private constructor C()
|
|
||||||
public const final val a: kotlin.Int = 18
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user