[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.psi
import org.jetbrains.kotlin.fir.realPsi import org.jetbrains.kotlin.fir.realPsi
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference 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.FirConstructorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol 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.name.Name
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.parents import org.jetbrains.kotlin.psi.psiUtil.parents
@@ -145,7 +149,27 @@ internal object FirAnnotationValueConverter {
is FirGetClassCall -> { is FirGetClassCall -> {
val symbol = (argument as? FirResolvedQualifier)?.symbol val symbol = (argument as? FirResolvedQualifier)?.symbol
when { 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.isLocal -> KtKClassAnnotationValue.KtLocalKClassAnnotationValue(
symbol.fir.psi as KtClassOrObject, symbol.fir.psi as KtClassOrObject,
sourcePsi sourcePsi
@@ -97,6 +97,7 @@ public sealed class KtKClassAnnotationValue : KtAnnotationValue() {
*/ */
public class KtErrorClassAnnotationValue( public class KtErrorClassAnnotationValue(
override val sourcePsi: KtElement?, override val sourcePsi: KtElement?,
public val unresolvedQualifierName: String?,
) : KtKClassAnnotationValue() ) : KtKClassAnnotationValue()
} }
@@ -127,4 +128,4 @@ public class KtConstantAnnotationValue(
* Render annotation value, resulted string is a valid Kotlin source code. * Render annotation value, resulted string is a valid Kotlin source code.
*/ */
public fun KtAnnotationValue.renderAsSourceCode(): String = public fun KtAnnotationValue.renderAsSourceCode(): String =
KtAnnotationValueRenderer.render(this) KtAnnotationValueRenderer.render(this)
@@ -201,16 +201,18 @@ internal fun KtAnnotationValue.toAnnotationMemberValue(parent: PsiElement): PsiA
} }
KtUnsupportedAnnotationValue -> null KtUnsupportedAnnotationValue -> null
is KtKClassAnnotationValue.KtErrorClassAnnotationValue -> null is KtKClassAnnotationValue -> toAnnotationMemberValue(parent)
is KtKClassAnnotationValue.KtLocalKClassAnnotationValue -> null
is KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue -> toAnnotationMemberValue(parent)
} }
} }
private fun KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue.toAnnotationMemberValue(parent: PsiElement): PsiExpression? { private fun KtKClassAnnotationValue.toAnnotationMemberValue(parent: PsiElement): PsiExpression? {
val fqName = classId.asSingleFqName() val typeString = when (this) {
is KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue -> classId.asSingleFqName().asString()
is KtKClassAnnotationValue.KtLocalKClassAnnotationValue -> null
is KtKClassAnnotationValue.KtErrorClassAnnotationValue -> unresolvedQualifierName
} ?: return null
val canonicalText = psiType( 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) ).let(TypeConversionUtil::erasure).getCanonicalText(false)
return try { return try {
PsiElementFactory.getInstance(parent.project).createExpressionFromText("$canonicalText.class", parent) 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"); 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 @Test
@TestMetadata("VarArgs.kt") @TestMetadata("VarArgs.kt")
public void testVarArgs() throws Exception { public void testVarArgs() throws Exception {
@@ -270,12 +270,6 @@ public class SymbolLightClassesParentingForLibraryTestGenerated extends Abstract
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/TypePararametersInClass.kt"); 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 @Test
@TestMetadata("VarArgs.kt") @TestMetadata("VarArgs.kt")
public void testVarArgs() throws Exception { public void testVarArgs() throws Exception {
@@ -270,12 +270,6 @@ public class SymbolLightClassesByFqNameForSourceTestGenerated extends AbstractSy
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/TypePararametersInClass.kt"); 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 @Test
@TestMetadata("VarArgs.kt") @TestMetadata("VarArgs.kt")
public void testVarArgs() throws Exception { public void testVarArgs() throws Exception {
@@ -411,6 +405,12 @@ public class SymbolLightClassesByFqNameForSourceTestGenerated extends AbstractSy
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/compilationErrors/TwoOverrides.kt"); 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 @Test
@TestMetadata("WrongAnnotations.kt") @TestMetadata("WrongAnnotations.kt")
public void testWrongAnnotations() throws Exception { public void testWrongAnnotations() throws Exception {
@@ -270,12 +270,6 @@ public class SymbolLightClassesParentingForSourceTestGenerated extends AbstractS
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/TypePararametersInClass.kt"); 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 @Test
@TestMetadata("VarArgs.kt") @TestMetadata("VarArgs.kt")
public void testVarArgs() throws Exception { public void testVarArgs() throws Exception {
@@ -411,6 +405,12 @@ public class SymbolLightClassesParentingForSourceTestGenerated extends AbstractS
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/compilationErrors/TwoOverrides.kt"); 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 @Test
@TestMetadata("WrongAnnotations.kt") @TestMetadata("WrongAnnotations.kt")
public void testWrongAnnotations() throws Exception { 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"); 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") @TestMetadata("VarArgs.kt")
public void testVarArgs() throws Exception { public void testVarArgs() throws Exception {
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/VarArgs.kt"); 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"); 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") @TestMetadata("WrongAnnotations.kt")
public void testWrongAnnotations() throws Exception { public void testWrongAnnotations() throws Exception {
runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/compilationErrors/WrongAnnotations.kt"); runTest("compiler/testData/asJava/lightClasses/lightClassByFqName/compilationErrors/WrongAnnotations.kt");