[AA LC] Save unresolved qualifier name in arguments of annotations

This commit is contained in:
Dmitriy Novozhilov
2022-09-28 14:37:11 +03:00
committed by Space Team
parent ed867af01d
commit 95f5848e6c
11 changed files with 66 additions and 37 deletions
@@ -17,9 +17,13 @@ import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.realPsi
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedTypeQualifierError
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.fir.types.ConeErrorType
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.parents
@@ -145,7 +149,27 @@ internal object FirAnnotationValueConverter {
is FirGetClassCall -> {
val symbol = (argument as? FirResolvedQualifier)?.symbol
when {
symbol == null -> KtKClassAnnotationValue.KtErrorClassAnnotationValue(sourcePsi)
symbol == null -> {
val qualifierParts = mutableListOf<String?>()
fun process(expression: FirExpression) {
val errorType = expression.typeRef.coneType as? ConeErrorType
val unresolvedName = when (val diagnostic = errorType?.diagnostic) {
is ConeUnresolvedTypeQualifierError -> diagnostic.qualifier
is ConeUnresolvedNameError -> diagnostic.qualifier
else -> null
}
qualifierParts += unresolvedName
if (errorType != null && expression is FirPropertyAccessExpression) {
expression.explicitReceiver?.let { process(it) }
}
}
process(argument)
val unresolvedName = qualifierParts.asReversed().filterNotNull().takeIf { it.isNotEmpty() }?.joinToString(".")
KtKClassAnnotationValue.KtErrorClassAnnotationValue(sourcePsi, unresolvedName)
}
symbol.isLocal -> KtKClassAnnotationValue.KtLocalKClassAnnotationValue(
symbol.fir.psi as KtClassOrObject,
sourcePsi
@@ -97,6 +97,7 @@ public sealed class KtKClassAnnotationValue : KtAnnotationValue() {
*/
public class KtErrorClassAnnotationValue(
override val sourcePsi: KtElement?,
public val unresolvedQualifierName: String?,
) : KtKClassAnnotationValue()
}
@@ -127,4 +128,4 @@ public class KtConstantAnnotationValue(
* Render annotation value, resulted string is a valid Kotlin source code.
*/
public fun KtAnnotationValue.renderAsSourceCode(): String =
KtAnnotationValueRenderer.render(this)
KtAnnotationValueRenderer.render(this)
@@ -201,16 +201,18 @@ internal fun KtAnnotationValue.toAnnotationMemberValue(parent: PsiElement): PsiA
}
KtUnsupportedAnnotationValue -> null
is KtKClassAnnotationValue.KtErrorClassAnnotationValue -> null
is KtKClassAnnotationValue.KtLocalKClassAnnotationValue -> null
is KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue -> toAnnotationMemberValue(parent)
is KtKClassAnnotationValue -> toAnnotationMemberValue(parent)
}
}
private fun KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue.toAnnotationMemberValue(parent: PsiElement): PsiExpression? {
val fqName = classId.asSingleFqName()
private fun KtKClassAnnotationValue.toAnnotationMemberValue(parent: PsiElement): PsiExpression? {
val typeString = when (this) {
is KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue -> classId.asSingleFqName().asString()
is KtKClassAnnotationValue.KtLocalKClassAnnotationValue -> null
is KtKClassAnnotationValue.KtErrorClassAnnotationValue -> unresolvedQualifierName
} ?: return null
val canonicalText = psiType(
fqName.asString(), parent, boxPrimitiveType = false, /* TODO value.arrayNestedness > 0*/
typeString, parent, boxPrimitiveType = false, /* TODO value.arrayNestedness > 0*/
).let(TypeConversionUtil::erasure).getCanonicalText(false)
return try {
PsiElementFactory.getInstance(parent.project).createExpressionFromText("$canonicalText.class", parent)
@@ -270,12 +270,6 @@ public class SymbolLightClassesByFqNameForLibraryTestGenerated extends AbstractS
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/TypePararametersInClass.kt");
}
@Test
@TestMetadata("typealiasInTypeArguments.kt")
public void testTypealiasInTypeArguments() throws Exception {
runTest("compiler/testData/asJava/lightClasses/typealiasInTypeArguments.kt");
}
@Test
@TestMetadata("VarArgs.kt")
public void testVarArgs() throws Exception {
@@ -270,12 +270,6 @@ public class SymbolLightClassesParentingForLibraryTestGenerated extends Abstract
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/TypePararametersInClass.kt");
}
@Test
@TestMetadata("typealiasInTypeArguments.kt")
public void testTypealiasInTypeArguments() throws Exception {
runTest("compiler/testData/asJava/lightClasses/typealiasInTypeArguments.kt");
}
@Test
@TestMetadata("VarArgs.kt")
public void testVarArgs() throws Exception {
@@ -270,12 +270,6 @@ public class SymbolLightClassesByFqNameForSourceTestGenerated extends AbstractSy
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/TypePararametersInClass.kt");
}
@Test
@TestMetadata("typealiasInTypeArguments.kt")
public void testTypealiasInTypeArguments() throws Exception {
runTest("compiler/testData/asJava/lightClasses/typealiasInTypeArguments.kt");
}
@Test
@TestMetadata("VarArgs.kt")
public void testVarArgs() throws Exception {
@@ -411,6 +405,12 @@ public class SymbolLightClassesByFqNameForSourceTestGenerated extends AbstractSy
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/compilationErrors/TwoOverrides.kt");
}
@Test
@TestMetadata("unresolvedQuialifierInAnnotation.kt")
public void testUnresolvedQuialifierInAnnotation() throws Exception {
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/compilationErrors/unresolvedQuialifierInAnnotation.kt");
}
@Test
@TestMetadata("WrongAnnotations.kt")
public void testWrongAnnotations() throws Exception {
@@ -270,12 +270,6 @@ public class SymbolLightClassesParentingForSourceTestGenerated extends AbstractS
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/TypePararametersInClass.kt");
}
@Test
@TestMetadata("typealiasInTypeArguments.kt")
public void testTypealiasInTypeArguments() throws Exception {
runTest("compiler/testData/asJava/lightClasses/typealiasInTypeArguments.kt");
}
@Test
@TestMetadata("VarArgs.kt")
public void testVarArgs() throws Exception {
@@ -411,6 +405,12 @@ public class SymbolLightClassesParentingForSourceTestGenerated extends AbstractS
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/compilationErrors/TwoOverrides.kt");
}
@Test
@TestMetadata("unresolvedQuialifierInAnnotation.kt")
public void testUnresolvedQuialifierInAnnotation() throws Exception {
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/compilationErrors/unresolvedQuialifierInAnnotation.kt");
}
@Test
@TestMetadata("WrongAnnotations.kt")
public void testWrongAnnotations() throws Exception {
@@ -0,0 +1,4 @@
@Ann(kClass = some.name.Unresolved.class)
public final class A /* A*/ {
public A();// .ctor()
}
@@ -0,0 +1,4 @@
@Ann(kClass = some.name.Unresolved::class)
public final class A /* A*/ {
public A();// .ctor()
}
@@ -0,0 +1,6 @@
// A
annotation class Ann(val kClass: KClass<*>)
@Ann(some.name.Unresolved::class)
class A
@@ -234,11 +234,6 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/TypePararametersInClass.kt");
}
@TestMetadata("typealiasInTypeArguments.kt")
public void testTypealiasInTypeArguments() throws Exception {
runTest("compiler/testData/asJava/lightClasses/typealiasInTypeArguments.kt");
}
@TestMetadata("VarArgs.kt")
public void testVarArgs() throws Exception {
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/VarArgs.kt");
@@ -356,6 +351,11 @@ public class CompilerLightClassTestGenerated extends AbstractCompilerLightClassT
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/compilationErrors/TwoOverrides.kt");
}
@TestMetadata("unresolvedQuialifierInAnnotation.kt")
public void testUnresolvedQuialifierInAnnotation() throws Exception {
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/compilationErrors/unresolvedQuialifierInAnnotation.kt");
}
@TestMetadata("WrongAnnotations.kt")
public void testWrongAnnotations() throws Exception {
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/compilationErrors/WrongAnnotations.kt");