[AA FIR] FirLazyAnnotationTransformer: fix resolve contract violation
We can't reduce resolve to COMPILER_REQUIRED_ANNOTATIONS phase for annotations with arguments, because currently they don't have argument mapping ```stracktrace org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments: By now the annotations argument mapping should have been resolved at org.jetbrains.kotlin.analysis.api.fir.annotations.FirAnnotationUtilsKt.mapAnnotationParameters(firAnnotationUtils.kt:137) at org.jetbrains.kotlin.analysis.api.fir.FirUtilsKt.toKtAnnotationApplication(FirUtils.kt:79) at org.jetbrains.kotlin.analysis.api.fir.annotations.FirAnnotationUtilsKt.annotationsByClassId(firAnnotationUtils.kt:60) at org.jetbrains.kotlin.analysis.api.fir.annotations.FirAnnotationUtilsKt.annotationsByClassId$default(firAnnotationUtils.kt:46) ``` ^KT-57424 Fixed
This commit is contained in:
+6
-18
@@ -49,27 +49,15 @@ internal fun annotationsByClassId(
|
|||||||
useSiteTargetFilter: AnnotationUseSiteTargetFilter,
|
useSiteTargetFilter: AnnotationUseSiteTargetFilter,
|
||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
annotationContainer: FirAnnotationContainer = firSymbol.fir,
|
annotationContainer: FirAnnotationContainer = firSymbol.fir,
|
||||||
): List<KtAnnotationApplicationWithArgumentsInfo> =
|
): List<KtAnnotationApplicationWithArgumentsInfo> {
|
||||||
if (firSymbol.isFromCompilerRequiredAnnotationsPhase(classId)) {
|
return annotationContainer.resolvedAnnotationsWithArguments(firSymbol).mapIndexedNotNull { index, annotation ->
|
||||||
buildList {
|
if (!useSiteTargetFilter.isAllowed(annotation.useSiteTarget) || annotation.toAnnotationClassId(useSiteSession) != classId) {
|
||||||
// this loop by index is required to avoid possible ConcurrentModificationException
|
return@mapIndexedNotNull null
|
||||||
val annotations = annotationContainer.resolvedCompilerRequiredAnnotations(firSymbol)
|
|
||||||
for (index in annotations.indices) {
|
|
||||||
val annotation = annotations[index]
|
|
||||||
if (useSiteTargetFilter.isAllowed(annotation.useSiteTarget) && annotation.toAnnotationClassIdSafe(useSiteSession) == classId) {
|
|
||||||
add(annotation.toKtAnnotationApplication(useSiteSession, index))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
annotationContainer.resolvedAnnotationsWithArguments(firSymbol).mapIndexedNotNull { index, annotation ->
|
|
||||||
if (!useSiteTargetFilter.isAllowed(annotation.useSiteTarget) || annotation.toAnnotationClassId(useSiteSession) != classId) {
|
|
||||||
return@mapIndexedNotNull null
|
|
||||||
}
|
|
||||||
|
|
||||||
annotation.toKtAnnotationApplication(useSiteSession, index)
|
annotation.toKtAnnotationApplication(useSiteSession, index)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal fun annotations(
|
internal fun annotations(
|
||||||
firSymbol: FirBasedSymbol<*>,
|
firSymbol: FirBasedSymbol<*>,
|
||||||
|
|||||||
+12
-3
@@ -55,7 +55,7 @@ internal class GranularAnnotationsBox(
|
|||||||
return annotations.find { it.qualifiedName == qualifiedName }
|
return annotations.find { it.qualifiedName == qualifiedName }
|
||||||
}
|
}
|
||||||
|
|
||||||
specialAnnotationsList[qualifiedName]?.let { specialAnnotationClassId ->
|
specialAnnotationsListWithSafeArgumentsResolve[qualifiedName]?.let { specialAnnotationClassId ->
|
||||||
val annotationApplication = annotationsProvider[specialAnnotationClassId].firstOrNull() ?: return null
|
val annotationApplication = annotationsProvider[specialAnnotationClassId].firstOrNull() ?: return null
|
||||||
return SymbolLightLazyAnnotation(annotationsProvider, annotationApplication, owner)
|
return SymbolLightLazyAnnotation(annotationsProvider, annotationApplication, owner)
|
||||||
}
|
}
|
||||||
@@ -89,6 +89,15 @@ internal class GranularAnnotationsBox(
|
|||||||
/* fieldName = */ "cachedAnnotations",
|
/* fieldName = */ "cachedAnnotations",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We can safety reduce resolve only for annotations without arguments
|
||||||
|
*
|
||||||
|
* @see org.jetbrains.kotlin.fir.resolve.transformers.plugin.CompilerRequiredAnnotationsHelper
|
||||||
|
*/
|
||||||
|
private val specialAnnotationsListWithSafeArgumentsResolve: Map<String, ClassId> = listOf(
|
||||||
|
StandardClassIds.Annotations.JvmRecord,
|
||||||
|
).associateBy { it.asFqNameString() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.jetbrains.kotlin.fir.resolve.transformers.plugin.CompilerRequiredAnnotationsHelper
|
* @see org.jetbrains.kotlin.fir.resolve.transformers.plugin.CompilerRequiredAnnotationsHelper
|
||||||
*/
|
*/
|
||||||
@@ -96,7 +105,7 @@ internal class GranularAnnotationsBox(
|
|||||||
StandardClassIds.Annotations.Deprecated,
|
StandardClassIds.Annotations.Deprecated,
|
||||||
StandardClassIds.Annotations.DeprecatedSinceKotlin,
|
StandardClassIds.Annotations.DeprecatedSinceKotlin,
|
||||||
StandardClassIds.Annotations.WasExperimental,
|
StandardClassIds.Annotations.WasExperimental,
|
||||||
StandardClassIds.Annotations.JvmRecord,
|
StandardClassIds.Annotations.Target,
|
||||||
).associateBy { it.asFqNameString() }
|
).associateBy { it.asFqNameString() } + specialAnnotationsListWithSafeArgumentsResolve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
@kotlin.Deprecated(message = "", replaceWith = @ReplaceWith(expression = ""), level = kotlin.DeprecationLevel.ERROR)
|
||||||
|
public final class MyClass /* MyClass*/ {
|
||||||
|
public MyClass();// .ctor()
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// PSI: org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForClassOrObject
|
||||||
|
// EXPECTED: kotlin.Deprecated
|
||||||
|
|
||||||
|
@Deprecated("", ReplaceWith(""), level = DeprecationLevel.ERROR)
|
||||||
|
class MyC<caret>lass
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
|
||||||
|
@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.PARAMETER})
|
||||||
|
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.VALUE_PARAMETER})
|
||||||
|
public abstract @interface AnnotationClass /* AnnotationClass*/ {
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
// PSI: org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForAnnotationClass
|
||||||
|
// EXPECTED: kotlin.annotation.Target
|
||||||
|
|
||||||
|
@Target(AnnotationTarget.VALUE_PARAMETER)
|
||||||
|
annotation class Annotatio<caret>nClass
|
||||||
+12
@@ -24,6 +24,12 @@ public class SymbolLightClassesAnnotationEqualityForSourceTestGenerated extends
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/symbol-light-classes/testData/annotationsEquality"), Pattern.compile("^(.+)\\.(kt)$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/symbol-light-classes/testData/annotationsEquality"), Pattern.compile("^(.+)\\.(kt)$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("Deprecated.kt")
|
||||||
|
public void testDeprecated() throws Exception {
|
||||||
|
runTest("analysis/symbol-light-classes/testData/annotationsEquality/Deprecated.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("ExplicitRetension.kt")
|
@TestMetadata("ExplicitRetension.kt")
|
||||||
public void testExplicitRetension() throws Exception {
|
public void testExplicitRetension() throws Exception {
|
||||||
@@ -48,6 +54,12 @@ public class SymbolLightClassesAnnotationEqualityForSourceTestGenerated extends
|
|||||||
runTest("analysis/symbol-light-classes/testData/annotationsEquality/JvmRepeatable.kt");
|
runTest("analysis/symbol-light-classes/testData/annotationsEquality/JvmRepeatable.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("KotlinTargetFirst.kt")
|
||||||
|
public void testKotlinTargetFirst() throws Exception {
|
||||||
|
runTest("analysis/symbol-light-classes/testData/annotationsEquality/KotlinTargetFirst.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("OverrideMethod.kt")
|
@TestMetadata("OverrideMethod.kt")
|
||||||
public void testOverrideMethod() throws Exception {
|
public void testOverrideMethod() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user