FirConstChecks: support "Some string".length case properly

#KT-48165 Fixed
This commit is contained in:
Mikhail Glukhikh
2021-08-10 11:00:51 +03:00
parent f6413c41a0
commit b1bcbaf48f
3 changed files with 29 additions and 4 deletions
@@ -23,6 +23,16 @@ FILE: const.kt
public get(): R|kotlin/Int|
public final const val l: R|kotlin/Int| = R|/k|
public get(): R|kotlin/Int|
public final const val m: R|kotlin/String| = String(123).R|kotlin/Any.toString|()
public get(): R|kotlin/String|
public final const val n: R|kotlin/Int| = String(456).R|kotlin/String.length|
public get(): R|kotlin/Int|
public final val o: R|kotlin/String| = String(789)
public get(): R|kotlin/String|
public final const val p: R|kotlin/String| = R|/o|.R|kotlin/Any.toString|()
public get(): R|kotlin/String|
public final const val q: R|kotlin/Int| = R|/o|.R|kotlin/String.length|
public get(): R|kotlin/Int|
public final class ForConst : R|kotlin/Any| {
public constructor(): R|ForConst| {
super<R|kotlin/Any|>()
@@ -18,6 +18,11 @@ const val i = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>ForConst.one() + "one"<!>
const val j = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>4 * ForConst.two()<!>
val k = 3 - ForConst.two()
const val l = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>k<!>
const val m = "123".toString()
const val n = "456".length
val o = "789"
const val p = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>o.toString()<!>
const val q = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>o.length<!>
class ForConst{
companion object {
@@ -160,8 +160,20 @@ internal fun checkConstantArguments(
}
}
expression is FirQualifiedAccessExpression -> {
val propertySymbol = expressionSymbol as? FirPropertySymbol ?: return ConstantArgumentKind.NOT_CONST
@OptIn(SymbolInternals::class)
val property = propertySymbol.fir
when {
(expressionSymbol as FirPropertySymbol).isLocal || expressionSymbol.callableId.className?.isRoot == false ->
property.name.asString() == "length" -> {
val coneType =
expression.dispatchReceiver.typeRef.coneTypeSafe<ConeKotlinType>() ?: return ConstantArgumentKind.NOT_CONST
val receiverClassId = coneType.lowerBoundIfFlexible().classId
if (receiverClassId == StandardClassIds.String) {
return checkConstantArguments(expression.dispatchReceiver, session)
}
}
propertySymbol.isLocal || propertySymbol.callableId.className?.isRoot == false ->
return ConstantArgumentKind.NOT_CONST
expression.typeRef.coneType.classId == StandardClassIds.KClass ->
return ConstantArgumentKind.NOT_KCLASS_LITERAL
@@ -170,9 +182,7 @@ internal fun checkConstantArguments(
expression.dispatchReceiver is FirThisReceiverExpression ->
return null
}
@OptIn(SymbolInternals::class)
val property = expressionSymbol.fir as? FirProperty
return when (property?.initializer) {
return when (property.initializer) {
is FirConstExpression<*> -> {
if (property.isVal)
ConstantArgumentKind.NOT_CONST_VAL_IN_CONST_EXPRESSION