[FIR] FirJavaFacade: fix contract violation from annotations

`isJavaDeprecatedAnnotation` can't be used here because it triggers
the resolution of an annotation ClassId

^KT-62705 Fixed
This commit is contained in:
Dmitrii Gridin
2023-10-19 22:14:58 +02:00
committed by Space Team
parent 931c2ce47a
commit d689c1a38f
10 changed files with 110 additions and 15 deletions
@@ -1884,6 +1884,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/annotations/Deprecated.kt");
}
@Test
@TestMetadata("DeprecatedInJavaDoc.kt")
public void testDeprecatedInJavaDoc() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/DeprecatedInJavaDoc.kt");
}
@Test
@TestMetadata("DeprecationOnAny.kt")
public void testDeprecationOnAny() throws Exception {
@@ -1884,6 +1884,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/annotations/Deprecated.kt");
}
@Test
@TestMetadata("DeprecatedInJavaDoc.kt")
public void testDeprecatedInJavaDoc() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/DeprecatedInJavaDoc.kt");
}
@Test
@TestMetadata("DeprecationOnAny.kt")
public void testDeprecationOnAny() throws Exception {
@@ -1884,6 +1884,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/annotations/Deprecated.kt");
}
@Test
@TestMetadata("DeprecatedInJavaDoc.kt")
public void testDeprecatedInJavaDoc() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/DeprecatedInJavaDoc.kt");
}
@Test
@TestMetadata("DeprecationOnAny.kt")
public void testDeprecationOnAny() throws Exception {
@@ -1890,6 +1890,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/annotations/Deprecated.kt");
}
@Test
@TestMetadata("DeprecatedInJavaDoc.kt")
public void testDeprecatedInJavaDoc() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/DeprecatedInJavaDoc.kt");
}
@Test
@TestMetadata("DeprecationOnAny.kt")
public void testDeprecationOnAny() throws Exception {
@@ -42,9 +42,6 @@ import org.jetbrains.kotlin.load.java.JavaClassFinder
import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.load.java.structure.impl.JavaElementImpl
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaClass
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.name.*
import org.jetbrains.kotlin.types.Variance.INVARIANT
@@ -244,9 +241,7 @@ abstract class FirJavaFacade(
return buildJavaClass {
resolvePhase = FirResolvePhase.BODY_RESOLVE
javaAnnotations += javaClass.annotations
if (javaClass.isDeprecatedInJavaDoc && javaAnnotations.none { it.isJavaDeprecatedAnnotation() }) {
javaAnnotations += DeprecatedInJavaDocAnnotation
}
isDeprecatedInJavaDoc = javaClass.isDeprecatedInJavaDoc
source = javaClass.toSourceElement()
this.moduleData = moduleData
symbol = classSymbol
@@ -50,7 +50,8 @@ class FirJavaClass @FirImplementationDetail internal constructor(
override val typeParameters: MutableList<FirTypeParameterRef>,
internal val javaPackage: JavaPackage?,
val javaTypeParameterStack: JavaTypeParameterStack,
internal val existingNestedClassifierNames: List<Name>
internal val existingNestedClassifierNames: List<Name>,
private val isDeprecatedInJavaDoc: Boolean,
) : FirRegularClass() {
override val hasLazyNestedClassifiers: Boolean get() = true
override val controlFlowGraphReference: FirControlFlowGraphReference? get() = null
@@ -75,7 +76,7 @@ class FirJavaClass @FirImplementationDetail internal constructor(
// TODO: the lazy annotations is a workaround for KT-55387, some non-lazy solution should probably be used instead
override val annotations: List<FirAnnotation> by lazy {
unEnhancedAnnotations.convertAnnotationsToFir(moduleData.session)
unEnhancedAnnotations.convertAnnotationsToFir(moduleData.session, isDeprecatedInJavaDoc)
}
// TODO: the lazy deprecationsProvider is a workaround for KT-55387, some non-lazy solution should probably be used instead
@@ -157,6 +158,7 @@ class FirJavaClassBuilder : FirRegularClassBuilder(), FirAnnotationContainerBuil
var javaPackage: JavaPackage? = null
lateinit var javaTypeParameterStack: JavaTypeParameterStack
val existingNestedClassifierNames: MutableList<Name> = mutableListOf()
var isDeprecatedInJavaDoc: Boolean = false
override var source: KtSourceElement? = null
override var resolvePhase: FirResolvePhase = FirResolvePhase.RAW_FIR
@@ -184,7 +186,8 @@ class FirJavaClassBuilder : FirRegularClassBuilder(), FirAnnotationContainerBuil
typeParameters,
javaPackage,
javaTypeParameterStack,
existingNestedClassifierNames
existingNestedClassifierNames,
isDeprecatedInJavaDoc,
)
}
@@ -5,9 +5,6 @@
package org.jetbrains.kotlin.fir.java
import com.intellij.patterns.PsiJavaPatterns.psiAnnotation
import org.jetbrains.kotlin.KtFakeSourceElement
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirElement
@@ -46,19 +43,19 @@ import org.jetbrains.kotlin.name.*
import org.jetbrains.kotlin.toKtPsiSourceElement
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment
import java.util.*
internal fun Iterable<JavaAnnotation>.convertAnnotationsToFir(
session: FirSession,
): List<FirAnnotation> = map { it.toFirAnnotationCall(session) }
internal fun JavaAnnotationOwner.convertAnnotationsToFir(
internal fun Iterable<JavaAnnotation>.convertAnnotationsToFir(
session: FirSession,
isDeprecatedInJavaDoc: Boolean,
): List<FirAnnotation> = buildList {
var isDeprecated = false
annotations.mapTo(this) {
this@convertAnnotationsToFir.mapTo(this) {
if (it.isJavaDeprecatedAnnotation()) isDeprecated = true
it.toFirAnnotationCall(session)
}
@@ -68,6 +65,10 @@ internal fun JavaAnnotationOwner.convertAnnotationsToFir(
}
}
internal fun JavaAnnotationOwner.convertAnnotationsToFir(
session: FirSession,
): List<FirAnnotation> = annotations.convertAnnotationsToFir(session, isDeprecatedInJavaDoc)
internal object DeprecatedInJavaDocAnnotation : JavaAnnotation {
override val arguments: Collection<JavaAnnotationArgument> get() = emptyList()
override val classId: ClassId get() = JvmStandardClassIds.Annotations.Java.Deprecated
@@ -0,0 +1,33 @@
// FILE: usage.kt
package first
import <!DEPRECATION!>third.JavaClass.NestedJavaClass<!>
// FILE: KotlinAnnotation.kt
package second
class KotlinClass {
fun foo(i: Int) {}
annotation class KotlinAnnotation
}
// FILE: third/JavaClass.java
package third;
import second.KotlinClass.*;
import static second.KotlinClass.*;
/**
* @deprecated deprecated message
*/
@KotlinAnnotation
public class JavaClass {
/**
* @deprecated deprecated message
*/
@KotlinAnnotation
public static class NestedJavaClass {
}
}
@@ -0,0 +1,33 @@
// FILE: usage.kt
package first
import third.<!DEPRECATION!>JavaClass<!>.<!DEPRECATION!>NestedJavaClass<!>
// FILE: KotlinAnnotation.kt
package second
class KotlinClass {
fun foo(i: Int) {}
annotation class KotlinAnnotation
}
// FILE: third/JavaClass.java
package third;
import second.KotlinClass.*;
import static second.KotlinClass.*;
/**
* @deprecated deprecated message
*/
@KotlinAnnotation
public class JavaClass {
/**
* @deprecated deprecated message
*/
@KotlinAnnotation
public static class NestedJavaClass {
}
}
@@ -1890,6 +1890,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/annotations/Deprecated.kt");
}
@Test
@TestMetadata("DeprecatedInJavaDoc.kt")
public void testDeprecatedInJavaDoc() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/DeprecatedInJavaDoc.kt");
}
@Test
@TestMetadata("DeprecationOnAny.kt")
public void testDeprecationOnAny() throws Exception {