FIR. Refactor smart-cast representation in FIR tree
Make smart-casts non-transparent expression without delegation to underlying FirQualifiedAccessExpression, as children delegation in fir tree has unclear semantics Remove two different kinds of tree nodes for smart-casts
This commit is contained in:
committed by
teamcity
parent
bc9db58b3c
commit
513af2dfbc
+5
-2
@@ -201,6 +201,9 @@ internal class KtFirCallResolver(
|
||||
resolveCalleeExpressionOfFunctionCall,
|
||||
resolveFragmentOfCall
|
||||
)
|
||||
is FirSmartCastExpression -> originalExpression.toKtCallInfo(
|
||||
psi, resolveCalleeExpressionOfFunctionCall, resolveFragmentOfCall
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -465,7 +468,7 @@ internal class KtFirCallResolver(
|
||||
isImplicitInvoke
|
||||
)
|
||||
}
|
||||
is FirExpressionWithSmartcast -> createKtCall(psi, fir.originalExpression, candidate, resolveFragmentOfCall)
|
||||
is FirSmartCastExpression -> (fir.originalExpression as? FirResolvable)?.let { createKtCall(psi, it, candidate, resolveFragmentOfCall) }
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -707,7 +710,7 @@ internal class KtFirCallResolver(
|
||||
private fun FirExpression.toKtReceiverValue(): KtReceiverValue? {
|
||||
val psi = psi
|
||||
return when (this) {
|
||||
is FirExpressionWithSmartcast -> {
|
||||
is FirSmartCastExpression -> {
|
||||
val result = originalExpression.toKtReceiverValue()
|
||||
if (result != null && isStable) {
|
||||
KtSmartCastedReceiverValue(result, smartcastType.coneType.asKtType())
|
||||
|
||||
+6
-5
@@ -231,11 +231,12 @@ internal class KtFirExpressionTypeProvider(
|
||||
}
|
||||
|
||||
when (val fir = expression.getOrBuildFir(analysisSession.firResolveSession)) {
|
||||
is FirExpressionWithSmartcastToNothing -> if (fir.isStable) {
|
||||
return DefiniteNullability.DEFINITELY_NULL
|
||||
}
|
||||
is FirExpressionWithSmartcast -> if (fir.isStable && fir.isNotNullable()) {
|
||||
return DefiniteNullability.DEFINITELY_NOT_NULL
|
||||
is FirSmartCastExpression -> if (fir.isStable) {
|
||||
if (fir.smartcastTypeWithoutNullableNothing != null) {
|
||||
return DefiniteNullability.DEFINITELY_NULL
|
||||
} else if (fir.isNotNullable()) {
|
||||
return DefiniteNullability.DEFINITELY_NOT_NULL
|
||||
}
|
||||
}
|
||||
is FirExpression -> if (fir.isNotNullable()) {
|
||||
return DefiniteNullability.DEFINITELY_NOT_NULL
|
||||
|
||||
+7
-9
@@ -12,10 +12,7 @@ import org.jetbrains.kotlin.analysis.api.components.KtSmartCastProvider
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast
|
||||
import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirSafeCallExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||
import org.jetbrains.kotlin.fir.types.isStableSmartcast
|
||||
@@ -45,15 +42,15 @@ internal class KtFirSmartcastProvider(
|
||||
this is KtParenthesizedExpression
|
||||
}
|
||||
|
||||
private fun getMatchingFirExpressionWithSmartCast(expression: KtExpression): FirExpressionWithSmartcast? {
|
||||
private fun getMatchingFirExpressionWithSmartCast(expression: KtExpression): FirSmartCastExpression? {
|
||||
if (!expression.isExplicitSmartCastInfoTarget) return null
|
||||
|
||||
val possibleFunctionCall = expression.getPossiblyQualifiedCallExpressionForCallee() ?: expression
|
||||
|
||||
return when (val firExpression = possibleFunctionCall.getOrBuildFir(analysisSession.firResolveSession)) {
|
||||
is FirExpressionWithSmartcast -> firExpression
|
||||
is FirSafeCallExpression -> firExpression.selector as? FirExpressionWithSmartcast
|
||||
is FirImplicitInvokeCall -> firExpression.explicitReceiver as? FirExpressionWithSmartcast
|
||||
is FirSmartCastExpression -> firExpression
|
||||
is FirSafeCallExpression -> firExpression.selector as? FirSmartCastExpression
|
||||
is FirImplicitInvokeCall -> firExpression.explicitReceiver as? FirSmartCastExpression
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -63,7 +60,7 @@ internal class KtFirSmartcastProvider(
|
||||
return getSmartCastedInfo(firSmartCastExpression)
|
||||
}
|
||||
|
||||
private fun getSmartCastedInfo(expression: FirExpressionWithSmartcast): KtSmartCastInfo? {
|
||||
private fun getSmartCastedInfo(expression: FirSmartCastExpression): KtSmartCastInfo? {
|
||||
val type = expression.smartcastType.coneTypeSafe<ConeKotlinType>()?.asKtType() ?: return null
|
||||
return KtSmartCastInfo(type, expression.isStable, token)
|
||||
}
|
||||
@@ -82,6 +79,7 @@ internal class KtFirSmartcastProvider(
|
||||
return when (val firExpression = wholeExpression.getOrBuildFir(analysisSession.firResolveSession)) {
|
||||
is FirQualifiedAccessExpression -> firExpression
|
||||
is FirSafeCallExpression -> firExpression.selector as? FirQualifiedAccessExpression
|
||||
is FirSmartCastExpression -> firExpression.originalExpression as? FirQualifiedAccessExpression
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
+6
-2
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.resolve.dfa.unwrapSmartcastExpression
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -188,7 +189,10 @@ internal object FirReferenceResolveHelper {
|
||||
if (expression.isSyntheticOperatorReference()) return emptyList()
|
||||
val symbolBuilder = analysisSession.firSymbolBuilder
|
||||
val adjustedResolutionExpression = adjustResolutionExpression(expression)
|
||||
val fir = adjustedResolutionExpression.getOrBuildFir(analysisSession.firResolveSession)
|
||||
val fir = when (val baseFir = adjustedResolutionExpression.getOrBuildFir(analysisSession.firResolveSession)) {
|
||||
is FirSmartCastExpression -> baseFir.originalExpression
|
||||
else -> baseFir
|
||||
}
|
||||
val session = analysisSession.firResolveSession.useSiteFirSession
|
||||
return when (fir) {
|
||||
is FirResolvedTypeRef -> getSymbolsForResolvedTypeRef(fir, expression, session, symbolBuilder)
|
||||
@@ -361,7 +365,7 @@ internal object FirReferenceResolveHelper {
|
||||
return listOfNotNull((fir.dispatchReceiver.typeRef as? FirResolvedTypeRef)?.toTargetSymbol(session, symbolBuilder))
|
||||
}
|
||||
val implicitInvokeReceiver = if (fir is FirImplicitInvokeCall) {
|
||||
fir.explicitReceiver as? FirQualifiedAccessExpression
|
||||
fir.explicitReceiver?.unwrapSmartcastExpression() as? FirQualifiedAccessExpression
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
+6
@@ -832,6 +832,12 @@ public class FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated extends Ab
|
||||
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/variableWithMemberInvoke.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("whenSelectorSmartCast.kt")
|
||||
public void testWhenSelectorSmartCast() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/whenSelectorSmartCast.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCall/assignments")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+6
@@ -46,6 +46,12 @@ public class FirIdeDependentAnalysisSourceModuleHLSmartCastInfoTestGenerated ext
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/smartCastProvider/smartCastInfo"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("bothImplicitReceiversSmartCast.kt")
|
||||
public void testBothImplicitReceiversSmartCast() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/smartCastProvider/smartCastInfo/bothImplicitReceiversSmartCast.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multiSmartcastAsReceiver_stable.kt")
|
||||
public void testMultiSmartcastAsReceiver_stable() throws Exception {
|
||||
|
||||
+6
@@ -46,6 +46,12 @@ public class FirIdeNormalAnalysisSourceModuleHLSmartCastInfoTestGenerated extend
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/smartCastProvider/smartCastInfo"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("bothImplicitReceiversSmartCast.kt")
|
||||
public void testBothImplicitReceiversSmartCast() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/smartCastProvider/smartCastInfo/bothImplicitReceiversSmartCast.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multiSmartcastAsReceiver_stable.kt")
|
||||
public void testMultiSmartcastAsReceiver_stable() throws Exception {
|
||||
|
||||
+12
@@ -460,6 +460,18 @@ public class FirIdeDependentAnalysisSourceModuleReferenceResolveTestGenerated ex
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/SeveralOverrides.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("smartCastExpression.kt")
|
||||
public void testSmartCastExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/smartCastExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("smartCastInvokeReceiver.kt")
|
||||
public void testSmartCastInvokeReceiver() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/smartCastInvokeReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SuperTypePrimaryConstructor.kt")
|
||||
public void testSuperTypePrimaryConstructor() throws Exception {
|
||||
|
||||
+12
@@ -460,6 +460,18 @@ public class FirIdeNormalAnalysisLibrarySourceModuleReferenceResolveTestGenerate
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/SeveralOverrides.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("smartCastExpression.kt")
|
||||
public void testSmartCastExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/smartCastExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("smartCastInvokeReceiver.kt")
|
||||
public void testSmartCastInvokeReceiver() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/smartCastInvokeReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SuperTypePrimaryConstructor.kt")
|
||||
public void testSuperTypePrimaryConstructor() throws Exception {
|
||||
|
||||
+12
@@ -460,6 +460,18 @@ public class FirIdeNormalAnalysisSourceModuleReferenceResolveTestGenerated exten
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/SeveralOverrides.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("smartCastExpression.kt")
|
||||
public void testSmartCastExpression() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/smartCastExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("smartCastInvokeReceiver.kt")
|
||||
public void testSmartCastInvokeReceiver() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/referenceResolve/smartCastInvokeReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SuperTypePrimaryConstructor.kt")
|
||||
public void testSuperTypePrimaryConstructor() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user