FIR IDE: split conversion utils for KtConstantValue to its own object
This commit is contained in:
committed by
Ilya Kirillov
parent
4c8d975ae5
commit
ce445700b8
+3
-3
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirElementError
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtCompileTimeConstantProvider
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.convertConstantExpression
|
||||
import org.jetbrains.kotlin.analysis.api.fir.evaluate.KtFirConstantValueConverter
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.*
|
||||
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
|
||||
@@ -25,8 +25,8 @@ internal class KtFirCompileTimeConstantProvider(
|
||||
override fun evaluate(expression: KtExpression): KtConstantValue? = withValidityAssertion {
|
||||
when (val fir = expression.getOrBuildFir(firResolveState)) {
|
||||
is FirExpression -> {
|
||||
FirCompileTimeConstantEvaluator().evaluate(fir)?.convertConstantExpression()
|
||||
?: fir.convertConstantExpression(firResolveState.rootModuleSession, firSymbolBuilder)
|
||||
FirCompileTimeConstantEvaluator().evaluate(fir)?.let { KtFirConstantValueConverter.toConstantValue(it) }
|
||||
?: KtFirConstantValueConverter.toConstantValue(fir, firResolveState.rootModuleSession, firSymbolBuilder)
|
||||
}
|
||||
else -> throwUnexpectedFirElementError(fir, expression)
|
||||
}
|
||||
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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.analysis.api.fir.evaluate
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
|
||||
import org.jetbrains.kotlin.analysis.api.fir.buildSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.*
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.realPsi
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.psi.KtCallElement
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.resolve.ArrayFqNames
|
||||
|
||||
internal object KtFirConstantValueConverter {
|
||||
|
||||
fun toNamedConstantValue(
|
||||
argumentMapping: Map<String, FirExpression>,
|
||||
session: FirSession,
|
||||
firSymbolBuilder: KtSymbolByFirBuilder
|
||||
): List<KtNamedConstantValue> =
|
||||
argumentMapping.map { (name, expression) ->
|
||||
KtNamedConstantValue(
|
||||
name,
|
||||
expression.convertConstantExpression(session, firSymbolBuilder) ?: KtUnsupportedConstantValue
|
||||
)
|
||||
}
|
||||
|
||||
fun <T> toConstantValue(
|
||||
firConstExpression: FirConstExpression<T>,
|
||||
): KtSimpleConstantValue<T> =
|
||||
firConstExpression.convertConstantExpression()
|
||||
|
||||
private fun <T> FirConstExpression<T>.convertConstantExpression(): KtSimpleConstantValue<T> =
|
||||
KtSimpleConstantValue(kind, value, realPsi as? KtElement)
|
||||
|
||||
private fun Collection<FirExpression>.convertConstantExpression(
|
||||
session: FirSession,
|
||||
firSymbolBuilder: KtSymbolByFirBuilder
|
||||
): Collection<KtConstantValue> =
|
||||
mapNotNull { it.convertConstantExpression(session, firSymbolBuilder) }
|
||||
|
||||
private fun Collection<KtConstantValue>.toArrayConstantValueIfNecessary(kotlinOrigin: KtElement?): KtConstantValue {
|
||||
return if (size == 1)
|
||||
single()
|
||||
else
|
||||
KtArrayConstantValue(this, kotlinOrigin)
|
||||
}
|
||||
|
||||
fun toConstantValue(
|
||||
firExpression: FirExpression,
|
||||
session: FirSession,
|
||||
firSymbolBuilder: KtSymbolByFirBuilder
|
||||
): KtConstantValue? =
|
||||
firExpression.convertConstantExpression(session, firSymbolBuilder)
|
||||
|
||||
private fun FirExpression.convertConstantExpression(
|
||||
session: FirSession,
|
||||
firSymbolBuilder: KtSymbolByFirBuilder
|
||||
): KtConstantValue? {
|
||||
return when (this) {
|
||||
is FirConstExpression<*> -> convertConstantExpression()
|
||||
is FirNamedArgumentExpression -> {
|
||||
expression.convertConstantExpression(session, firSymbolBuilder)
|
||||
}
|
||||
is FirVarargArgumentsExpression -> {
|
||||
arguments.convertConstantExpression(session, firSymbolBuilder)
|
||||
.toArrayConstantValueIfNecessary(realPsi as? KtElement)
|
||||
}
|
||||
is FirArrayOfCall -> {
|
||||
argumentList.arguments.convertConstantExpression(session, firSymbolBuilder)
|
||||
.toArrayConstantValueIfNecessary(realPsi as? KtElement)
|
||||
}
|
||||
is FirFunctionCall -> {
|
||||
val reference = calleeReference as? FirResolvedNamedReference ?: return null
|
||||
when (val resolvedSymbol = reference.resolvedSymbol) {
|
||||
is FirConstructorSymbol -> {
|
||||
val classSymbol = resolvedSymbol.getContainingClassSymbol(session) ?: return null
|
||||
if ((classSymbol.fir as? FirClass)?.classKind == ClassKind.ANNOTATION_CLASS) {
|
||||
val resultMap = mutableMapOf<String, FirExpression>()
|
||||
argumentMapping?.entries?.forEach { (arg, param) ->
|
||||
resultMap[param.name.asString()] = arg
|
||||
}
|
||||
KtAnnotationConstantValue(
|
||||
resolvedSymbol.callableId.className?.asString(),
|
||||
toNamedConstantValue(resultMap, session, firSymbolBuilder),
|
||||
this.realPsi as? KtCallElement
|
||||
)
|
||||
} else null
|
||||
}
|
||||
is FirNamedFunctionSymbol -> {
|
||||
if (resolvedSymbol.callableId.asSingleFqName() in ArrayFqNames.ARRAY_CALL_FQ_NAMES)
|
||||
argumentList.arguments.convertConstantExpression(session, firSymbolBuilder)
|
||||
.toArrayConstantValueIfNecessary(realPsi as? KtElement)
|
||||
else null
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
is FirPropertyAccessExpression -> {
|
||||
val reference = calleeReference as? FirResolvedNamedReference ?: return null
|
||||
when (val resolvedSymbol = reference.resolvedSymbol) {
|
||||
is FirEnumEntrySymbol -> {
|
||||
KtEnumEntryValue(resolvedSymbol.fir.buildSymbol(firSymbolBuilder) as KtEnumEntrySymbol, realPsi as? KtElement)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
else -> KtUnsupportedConstantValue
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -17,13 +17,13 @@ import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.analysis.api.fir.findPsi
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirModuleResolveState
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
|
||||
import org.jetbrains.kotlin.analysis.api.fir.evaluate.KtFirConstantValueConverter
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.annotations.containsAnnotation
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.annotations.getAnnotationClassIds
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.annotations.toAnnotationsList
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.KtFirMemberPropertySymbolPointer
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.createSignature
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.convertConstantExpression
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.firRef
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.weakRef
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtKotlinPropertySymbol
|
||||
@@ -72,7 +72,7 @@ internal class KtFirKotlinPropertySymbol(
|
||||
|
||||
override val isExtension: Boolean get() = firRef.withFir { it.receiverTypeRef != null }
|
||||
override val initializer: KtConstantValue? by firRef.withFirAndCache(FirResolvePhase.BODY_RESOLVE) { fir ->
|
||||
fir.initializer?.convertConstantExpression(resolveState.rootModuleSession, _builder)
|
||||
fir.initializer?.let { KtFirConstantValueConverter.toConstantValue(it, resolveState.rootModuleSession, _builder) }
|
||||
}
|
||||
override val symbolKind: KtSymbolKind
|
||||
get() = firRef.withFir { fir ->
|
||||
|
||||
+2
-2
@@ -15,12 +15,12 @@ import org.jetbrains.kotlin.fir.declarations.utils.isStatic
|
||||
import org.jetbrains.kotlin.analysis.api.fir.findPsi
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirModuleResolveState
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
|
||||
import org.jetbrains.kotlin.analysis.api.fir.evaluate.KtFirConstantValueConverter
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.annotations.containsAnnotation
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.annotations.getAnnotationClassIds
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.annotations.toAnnotationsList
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.KtFirJavaSyntheticPropertySymbolPointer
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.convertConstantExpression
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.firRef
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.weakRef
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.*
|
||||
@@ -60,7 +60,7 @@ internal class KtFirSyntheticJavaPropertySymbol(
|
||||
}
|
||||
override val isExtension: Boolean get() = firRef.withFir { it.receiverTypeRef != null }
|
||||
override val initializer: KtConstantValue? by firRef.withFirAndCache(FirResolvePhase.BODY_RESOLVE) { fir ->
|
||||
fir.initializer?.convertConstantExpression(resolveState.rootModuleSession, _builder)
|
||||
fir.initializer?.let { KtFirConstantValueConverter.toConstantValue(it, resolveState.rootModuleSession, _builder) }
|
||||
}
|
||||
|
||||
override val modality: Modality get() = getModality()
|
||||
|
||||
+6
-1
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.analysis.api.fir.symbols.annotations
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
|
||||
import org.jetbrains.kotlin.analysis.api.fir.evaluate.KtFirConstantValueConverter
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
@@ -41,7 +42,11 @@ internal class KtFirAnnotationCall(
|
||||
override val useSiteTarget: AnnotationUseSiteTarget? get() = annotationCallRef.useSiteTarget
|
||||
|
||||
override val arguments: List<KtNamedConstantValue> by containingDeclaration.withFirAndCache(ResolveType.AnnotationsArguments) { fir ->
|
||||
mapAnnotationParameters(annotationCallRef, fir.moduleData.session).toNamedConstantValue(fir.moduleData.session, _builder)
|
||||
KtFirConstantValueConverter.toNamedConstantValue(
|
||||
mapAnnotationParameters(annotationCallRef, fir.moduleData.session),
|
||||
fir.moduleData.session,
|
||||
_builder
|
||||
)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
package org.jetbrains.kotlin.analysis.api.fir.utils
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
|
||||
import org.jetbrains.kotlin.analysis.api.fir.buildSymbol
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.classKind
|
||||
@@ -22,19 +20,13 @@ 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.analysis.api.fir.getCandidateSymbols
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.*
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirModuleResolveState
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.withFirDeclaration
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.ResolveType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.realPsi
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.ArrayFqNames
|
||||
|
||||
internal fun PsiElement.unwrap(): PsiElement {
|
||||
return when (this) {
|
||||
@@ -98,89 +90,6 @@ internal fun mapAnnotationParameters(annotation: FirAnnotation, session: FirSess
|
||||
return resultSet
|
||||
}
|
||||
|
||||
internal fun Map<String, FirExpression>.toNamedConstantValue(
|
||||
session: FirSession,
|
||||
firSymbolBuilder: KtSymbolByFirBuilder
|
||||
): List<KtNamedConstantValue> =
|
||||
map { (name, expression) ->
|
||||
KtNamedConstantValue(
|
||||
name,
|
||||
expression.convertConstantExpression(session, firSymbolBuilder) ?: KtUnsupportedConstantValue
|
||||
)
|
||||
}
|
||||
|
||||
internal fun <T> FirConstExpression<T>.convertConstantExpression(): KtSimpleConstantValue<T> =
|
||||
KtSimpleConstantValue(kind, value, realPsi as? KtElement)
|
||||
|
||||
private fun Collection<FirExpression>.convertConstantExpression(
|
||||
session: FirSession,
|
||||
firSymbolBuilder: KtSymbolByFirBuilder
|
||||
): Collection<KtConstantValue> =
|
||||
mapNotNull { it.convertConstantExpression(session, firSymbolBuilder) }
|
||||
|
||||
private fun Collection<KtConstantValue>.toArrayConstantValueIfNecessary(kotlinOrigin: KtElement?): KtConstantValue {
|
||||
return if (size == 1)
|
||||
single()
|
||||
else
|
||||
KtArrayConstantValue(this, kotlinOrigin)
|
||||
}
|
||||
|
||||
internal fun FirExpression.convertConstantExpression(
|
||||
session: FirSession,
|
||||
firSymbolBuilder: KtSymbolByFirBuilder
|
||||
): KtConstantValue? {
|
||||
return when (this) {
|
||||
is FirConstExpression<*> -> convertConstantExpression()
|
||||
is FirNamedArgumentExpression -> {
|
||||
expression.convertConstantExpression(session, firSymbolBuilder)
|
||||
}
|
||||
is FirVarargArgumentsExpression -> {
|
||||
arguments.convertConstantExpression(session, firSymbolBuilder)
|
||||
.toArrayConstantValueIfNecessary(realPsi as? KtElement)
|
||||
}
|
||||
is FirArrayOfCall -> {
|
||||
argumentList.arguments.convertConstantExpression(session, firSymbolBuilder)
|
||||
.toArrayConstantValueIfNecessary(realPsi as? KtElement)
|
||||
}
|
||||
is FirFunctionCall -> {
|
||||
val reference = calleeReference as? FirResolvedNamedReference ?: return null
|
||||
when (val resolvedSymbol = reference.resolvedSymbol) {
|
||||
is FirConstructorSymbol -> {
|
||||
val classSymbol = resolvedSymbol.getContainingClassSymbol(session) ?: return null
|
||||
if ((classSymbol.fir as? FirClass)?.classKind == ClassKind.ANNOTATION_CLASS) {
|
||||
val resultMap = mutableMapOf<String, FirExpression>()
|
||||
argumentMapping?.entries?.forEach { (arg, param) ->
|
||||
resultMap[param.name.asString()] = arg
|
||||
}
|
||||
KtAnnotationConstantValue(
|
||||
resolvedSymbol.callableId.className?.asString(),
|
||||
resultMap.toNamedConstantValue(session, firSymbolBuilder),
|
||||
this.realPsi as? KtCallElement
|
||||
)
|
||||
} else null
|
||||
}
|
||||
is FirNamedFunctionSymbol -> {
|
||||
if (resolvedSymbol.callableId.asSingleFqName() in ArrayFqNames.ARRAY_CALL_FQ_NAMES)
|
||||
argumentList.arguments.convertConstantExpression(session, firSymbolBuilder)
|
||||
.toArrayConstantValueIfNecessary(realPsi as? KtElement)
|
||||
else null
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
is FirPropertyAccessExpression -> {
|
||||
val reference = calleeReference as? FirResolvedNamedReference ?: return null
|
||||
when (val resolvedSymbol = reference.resolvedSymbol) {
|
||||
is FirEnumEntrySymbol -> {
|
||||
KtEnumEntryValue(resolvedSymbol.fir.buildSymbol(firSymbolBuilder) as KtEnumEntrySymbol, realPsi as? KtElement)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
else -> KtUnsupportedConstantValue
|
||||
}
|
||||
}
|
||||
|
||||
internal fun KtTypeNullability.toConeNullability() = when (this) {
|
||||
KtTypeNullability.NULLABLE -> ConeNullability.NULLABLE
|
||||
KtTypeNullability.NON_NULLABLE -> ConeNullability.NOT_NULL
|
||||
|
||||
Reference in New Issue
Block a user