diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirKotlinPropertySymbol.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirKotlinPropertySymbol.kt index 8705648081f..28b0d1ec75b 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirKotlinPropertySymbol.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirKotlinPropertySymbol.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession +import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.containingClass @@ -39,6 +40,7 @@ import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.isExtension +import org.jetbrains.kotlin.fir.types.toRegularClassSymbol import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.Name @@ -68,7 +70,7 @@ internal class KtFirKotlinPropertySymbol( override val contextReceivers: List by cached { firSymbol.createContextReceivers(builder) } override val isExtension: Boolean get() = withValidityAssertion { firSymbol.isExtension } - override val initializer: KtInitializerValue? by cached { firSymbol.getKtConstantInitializer() } + override val initializer: KtInitializerValue? by cached { firSymbol.getKtConstantInitializer(firResolveSession) } override val symbolKind: KtSymbolKind get() = withValidityAssertion { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirSyntheticJavaPropertySymbol.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirSyntheticJavaPropertySymbol.kt index d19200efcaf..528386340c8 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirSyntheticJavaPropertySymbol.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/KtFirSyntheticJavaPropertySymbol.kt @@ -51,7 +51,7 @@ internal class KtFirSyntheticJavaPropertySymbol( override val isExtension: Boolean get() = withValidityAssertion { firSymbol.isExtension } - override val initializer: KtInitializerValue? by cached { firSymbol.getKtConstantInitializer() } + override val initializer: KtInitializerValue? by cached { firSymbol.getKtConstantInitializer(firResolveSession) } override val modality: Modality get() = withValidityAssertion { firSymbol.modality ?: firSymbol.invalidModalityError() } override val visibility: Visibility get() = withValidityAssertion { firSymbol.visibility } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/firSymbolUtils.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/firSymbolUtils.kt index ff01987ba31..18810553468 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/firSymbolUtils.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/firSymbolUtils.kt @@ -15,16 +15,18 @@ import org.jetbrains.kotlin.analysis.api.fir.utils.asKtInitializerValue import org.jetbrains.kotlin.analysis.api.impl.base.KtContextReceiverImpl import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol import org.jetbrains.kotlin.analysis.api.types.KtType +import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext -import org.jetbrains.kotlin.fir.declarations.FirContextReceiver -import org.jetbrains.kotlin.fir.declarations.FirDeclaration -import org.jetbrains.kotlin.fir.declarations.FirResolvePhase -import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression import org.jetbrains.kotlin.fir.psi +import org.jetbrains.kotlin.fir.references.impl.FirPropertyFromParameterResolvedNamedReference import org.jetbrains.kotlin.fir.renderer.FirRenderer import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase import org.jetbrains.kotlin.fir.symbols.impl.* +import org.jetbrains.kotlin.fir.types.toRegularClassSymbol import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.psi.KtDeclaration @@ -89,8 +91,21 @@ internal fun FirCallableSymbol<*>.dispatchReceiverType( return dispatchReceiverType?.let { builder.typeBuilder.buildKtType(it) } } -internal fun FirVariableSymbol<*>.getKtConstantInitializer(): KtInitializerValue? { +internal fun FirVariableSymbol<*>.getKtConstantInitializer(resolveSession: LLFirResolveSession): KtInitializerValue? { lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE) - val firInitializer = fir.initializer ?: return null - return firInitializer.asKtInitializerValue() -} \ No newline at end of file + var firInitializer = fir.initializer ?: return null + if (firInitializer is FirPropertyAccessExpression) { + val calleeReference = firInitializer.calleeReference + if (calleeReference is FirPropertyFromParameterResolvedNamedReference) { + val valueParameterSymbol = calleeReference.resolvedSymbol as? FirValueParameterSymbol + if (valueParameterSymbol != null) { + valueParameterSymbol.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE) + firInitializer = valueParameterSymbol.fir.defaultValue ?: firInitializer + } + } + } + val parentIsAnnotation = dispatchReceiverType + ?.toRegularClassSymbol(resolveSession.useSiteFirSession) + ?.classKind == ClassKind.ANNOTATION_CLASS + return firInitializer.asKtInitializerValue(moduleData.session, parentIsAnnotation) +} diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/utils/firUtils.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/utils/firUtils.kt index de221b1fb9d..8a0a03743d6 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/utils/firUtils.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/utils/firUtils.kt @@ -6,9 +6,11 @@ package org.jetbrains.kotlin.analysis.api.fir.utils import com.intellij.psi.PsiElement import org.jetbrains.kotlin.analysis.api.KtConstantInitializerValue +import org.jetbrains.kotlin.analysis.api.KtConstantValueForAnnotation import org.jetbrains.kotlin.analysis.api.KtInitializerValue import org.jetbrains.kotlin.analysis.api.KtNonConstantInitializerValue import org.jetbrains.kotlin.analysis.api.components.KtConstantEvaluationMode +import org.jetbrains.kotlin.analysis.api.fir.evaluate.FirAnnotationValueConverter import org.jetbrains.kotlin.analysis.api.fir.evaluate.FirCompileTimeConstantEvaluator import org.jetbrains.kotlin.analysis.api.fir.getCandidateSymbols import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability @@ -89,12 +91,24 @@ internal fun FirCallableSymbol<*>.computeImportableName(useSiteSession: FirSessi return if (canBeImported) callableId.asSingleFqName() else null } -internal fun FirExpression.asKtInitializerValue(): KtInitializerValue { +internal fun FirExpression.asKtInitializerValue( + session: FirSession, + forAnnotationDefaultValue: Boolean +): KtInitializerValue { val ktExpression = psi as? KtExpression val evaluated = FirCompileTimeConstantEvaluator.evaluateAsKtConstantValue(this, KtConstantEvaluationMode.CONSTANT_EXPRESSION_EVALUATION) return when (evaluated) { - null -> KtNonConstantInitializerValue(ktExpression) + null -> if (forAnnotationDefaultValue) { + val annotationConstantValue = FirAnnotationValueConverter.toConstantValue(this, session) + if (annotationConstantValue != null) { + KtConstantValueForAnnotation(annotationConstantValue, ktExpression) + } else { + KtNonConstantInitializerValue(ktExpression) + } + } else { + KtNonConstantInitializerValue(ktExpression) + } else -> KtConstantInitializerValue(evaluated, ktExpression) } } diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtInitializerValue.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtInitializerValue.kt index a35ab8c139c..8f2119dcea2 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtInitializerValue.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtInitializerValue.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.analysis.api +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationValue import org.jetbrains.kotlin.analysis.api.base.KtConstantValue import org.jetbrains.kotlin.psi.KtExpression @@ -29,10 +30,19 @@ public class KtConstantInitializerValue( ) : KtInitializerValue() /** - * Property intialzer which cannot be represented as Kotlin const value. + * Property initializer which cannot be represented as Kotlin const value. * * See [KtConstantInitializerValue] for more info. */ public class KtNonConstantInitializerValue( override val initializerPsi: KtExpression? -) : KtInitializerValue() \ No newline at end of file +) : KtInitializerValue() + +/** + * Initializer of property of annotation, which can not be which cannot be represented as Kotlin const value, + * but can be represented as [KtAnnotationValue] + */ +public class KtConstantValueForAnnotation( + public val annotationValue: KtAnnotationValue, + override val initializerPsi: KtExpression? +) : KtInitializerValue() diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/DebugSymbolRenderer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/DebugSymbolRenderer.kt index 4226d0419bf..9d1177a0957 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/DebugSymbolRenderer.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/DebugSymbolRenderer.kt @@ -6,10 +6,7 @@ package org.jetbrains.kotlin.analysis.api.symbols import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.KtConstantInitializerValue -import org.jetbrains.kotlin.analysis.api.KtInitializerValue -import org.jetbrains.kotlin.analysis.api.KtNonConstantInitializerValue +import org.jetbrains.kotlin.analysis.api.* import org.jetbrains.kotlin.analysis.api.annotations.* import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver import org.jetbrains.kotlin.analysis.api.components.KtSymbolContainingDeclarationProviderMixIn @@ -262,11 +259,18 @@ public object DebugSymbolRenderer { append(value.constant.renderAsKotlinConstant()) append(")") } + is KtNonConstantInitializerValue -> { append("KtNonConstantInitializerValue(") append(value.initializerPsi?.firstLineOfPsi() ?: "NO_PSI") append(")") } + + is KtConstantValueForAnnotation -> { + append("KtConstantValueForAnnotation(") + append(value.annotationValue.renderAsSourceCode()) + append(")") + } } } @@ -299,4 +303,4 @@ public object DebugSymbolRenderer { "org.jetbrains.kotlin.analysis.api.fir", "org.jetbrains.kotlin.analysis.api.descriptors", ) -} \ No newline at end of file +} diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt index 2e42f1d0278..1cc6e6e0472 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightAccessorMethod.kt @@ -7,6 +7,9 @@ package org.jetbrains.kotlin.light.classes.symbol.methods import com.intellij.psi.* import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.KtConstantInitializerValue +import org.jetbrains.kotlin.analysis.api.KtConstantValueForAnnotation +import org.jetbrains.kotlin.analysis.api.KtNonConstantInitializerValue import org.jetbrains.kotlin.analysis.api.lifetime.isValid import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode @@ -193,4 +196,18 @@ internal class SymbolLightAccessorMethod( override fun isValid(): Boolean = super.isValid() && propertyAccessorSymbol.isValid() override fun isOverride(): Boolean = propertyAccessorSymbol.isOverride + + private val _defaultValue: PsiAnnotationMemberValue? by lazyPub { + if (!containingClass.isAnnotationType) return@lazyPub null + when (val initializer = containingPropertySymbol.initializer) { + is KtConstantInitializerValue -> initializer.constant.createPsiLiteral(this) + is KtConstantValueForAnnotation -> initializer.annotationValue.toAnnotationMemberValue(this) + is KtNonConstantInitializerValue -> null + null -> null + } + } + + override fun getDefaultValue(): PsiAnnotationMemberValue? { + return _defaultValue + } } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightMethodBase.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightMethodBase.kt index bdc0b3451a0..8891814f9f4 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightMethodBase.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightMethodBase.kt @@ -88,7 +88,7 @@ internal abstract class SymbolLightMethodBase( override fun getThrowsList(): PsiReferenceList = KotlinLightReferenceListBuilder(manager, language, PsiReferenceList.Role.THROWS_LIST) //TODO() - override fun getDefaultValue(): PsiAnnotationMemberValue? = null //TODO() + override fun getDefaultValue(): PsiAnnotationMemberValue? = null protected fun T.computeJvmMethodName( defaultName: String, diff --git a/compiler/testData/asJava/lightClasses/AnnotationClass.kt b/compiler/testData/asJava/lightClasses/AnnotationClass.kt index bf464b4d4dc..5afed81c530 100644 --- a/compiler/testData/asJava/lightClasses/AnnotationClass.kt +++ b/compiler/testData/asJava/lightClasses/AnnotationClass.kt @@ -1,4 +1,6 @@ // Anno +// IGNORE_FIR +// Ignored due to KT-53573 annotation class Anno( val i: Int, diff --git a/compiler/testData/asJava/ultraLightClasses/annotations.fir.java b/compiler/testData/asJava/ultraLightClasses/annotations.fir.java index 889f5aa5130..df525fcb5cc 100644 --- a/compiler/testData/asJava/ultraLightClasses/annotations.fir.java +++ b/compiler/testData/asJava/ultraLightClasses/annotations.fir.java @@ -44,7 +44,7 @@ public static final class Companion /* AnnoWithCompanion.Companion*/ { public abstract @interface Anno /* Anno*/ { public abstract Anno[] x();// x() - public abstract java.lang.String p();// p() + public abstract java.lang.String p() default "";// p() }