[FIR] Introduce supertypes-for-annotation-class checker
This commit is contained in:
+5
@@ -379,6 +379,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/statusResolveForTypealiasAsSuperClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("supertypesForAnnotationClass.kt")
|
||||
public void testSupertypesForAnnotationClass() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/supertypesForAnnotationClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("syntheticsVsNormalProperties.kt")
|
||||
public void testSyntheticsVsNormalProperties() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/syntheticsVsNormalProperties.kt");
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
FILE: supertypesForAnnotationClass.kt
|
||||
public abstract interface SomeInterface : R|kotlin/Any| {
|
||||
}
|
||||
public abstract class SomeClass : R|kotlin/Any| {
|
||||
public constructor(): R|SomeClass| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final annotation class Ann : R|SomeInterface|, R|SomeClass|, R|kotlin/Annotation| {
|
||||
public constructor(): R|Ann| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final annotation class Ann2 : R|kotlin/Annotation| {
|
||||
public constructor(): R|Ann2| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final annotation class Ann3 : R|kotlin/Annotation|, R|kotlin/Annotation| {
|
||||
public constructor(): R|Ann3| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final class MyClass : R|SomeInterface|, R|SomeClass| {
|
||||
public constructor(): R|MyClass| {
|
||||
super<R|SomeClass|>()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
interface SomeInterface
|
||||
|
||||
abstract class SomeClass
|
||||
|
||||
annotation class Ann : <!SUPERTYPES_FOR_ANNOTATION_CLASS!>SomeInterface, SomeClass()<!>
|
||||
|
||||
annotation class Ann2
|
||||
|
||||
annotation class Ann3 : <!SUPERTYPES_FOR_ANNOTATION_CLASS!>Annotation<!>
|
||||
|
||||
class MyClass : SomeInterface, SomeClass()
|
||||
+6
@@ -446,6 +446,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/statusResolveForTypealiasAsSuperClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("supertypesForAnnotationClass.kt")
|
||||
public void testSupertypesForAnnotationClass() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/supertypesForAnnotationClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("syntheticsVsNormalProperties.kt")
|
||||
public void testSyntheticsVsNormalProperties() throws Exception {
|
||||
|
||||
+6
@@ -449,6 +449,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/statusResolveForTypealiasAsSuperClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("supertypesForAnnotationClass.kt")
|
||||
public void testSupertypesForAnnotationClass() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/supertypesForAnnotationClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("syntheticsVsNormalProperties.kt")
|
||||
public void testSyntheticsVsNormalProperties() throws Exception {
|
||||
|
||||
+1
@@ -53,6 +53,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
|
||||
ARRAY_ACCESS,
|
||||
NAME_OF_NAMED_ARGUMENT,
|
||||
VALUE_ARGUMENTS,
|
||||
SUPERTYPES_LIST,
|
||||
;
|
||||
|
||||
val expressionToCreate get() = "SourceElementPositioningStrategies.${strategy ?: name}"
|
||||
|
||||
+1
@@ -146,6 +146,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
}
|
||||
val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by error<FirSourceElement, KtTypeReference>()
|
||||
val VAR_ANNOTATION_PARAMETER by error<FirSourceElement, KtParameter>(PositioningStrategy.VAL_OR_VAR_NODE)
|
||||
val SUPERTYPES_FOR_ANNOTATION_CLASS by error<FirSourceElement, KtClass>(PositioningStrategy.SUPERTYPES_LIST)
|
||||
}
|
||||
|
||||
val EXPOSED_VISIBILITY by object : DiagnosticGroup("Exposed visibility") {
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
|
||||
@@ -139,6 +140,7 @@ object FirErrors {
|
||||
val NOT_AN_ANNOTATION_CLASS by error1<FirSourceElement, PsiElement, String>()
|
||||
val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by error0<FirSourceElement, KtTypeReference>()
|
||||
val VAR_ANNOTATION_PARAMETER by error0<FirSourceElement, KtParameter>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||
val SUPERTYPES_FOR_ANNOTATION_CLASS by error0<FirSourceElement, KtClass>(SourceElementPositioningStrategies.SUPERTYPES_LIST)
|
||||
|
||||
// Exposed visibility
|
||||
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3<FirSourceElement, KtNamedDeclaration, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||
|
||||
+4
@@ -26,6 +26,10 @@ object FirAnnotationClassDeclarationChecker : FirRegularClassChecker() {
|
||||
if (declaration.classKind != ANNOTATION_CLASS) return
|
||||
if (declaration.isLocal) reporter.reportOn(declaration.source, FirErrors.LOCAL_ANNOTATION_CLASS_ERROR, context)
|
||||
|
||||
if (declaration.superTypeRefs.size != 1) {
|
||||
reporter.reportOn(declaration.source, FirErrors.SUPERTYPES_FOR_ANNOTATION_CLASS, context)
|
||||
}
|
||||
|
||||
for (it in declaration.declarations) {
|
||||
when {
|
||||
it is FirConstructor && it.isPrimary -> {
|
||||
|
||||
+2
@@ -191,6 +191,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SEALED_SUPERTYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SEALED_SUPERTYPE_IN_LOCAL_CLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_INLINE_CLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPES_FOR_ANNOTATION_CLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_INITIALIZED_IN_INTERFACE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_NOT_A_CLASS_OR_INTERFACE
|
||||
@@ -345,6 +346,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
||||
map.put(INVALID_TYPE_OF_ANNOTATION_MEMBER, "Invalid type of annotation member")
|
||||
map.put(VAR_ANNOTATION_PARAMETER, "An annotation parameter cannot be 'var'")
|
||||
map.put(NOT_AN_ANNOTATION_CLASS, "Illegal annotation class: {0}", NULLABLE_STRING)
|
||||
map.put(SUPERTYPES_FOR_ANNOTATION_CLASS, "Annotation class cannot have supertypes")
|
||||
|
||||
// Exposed visibility group // #
|
||||
map.put(
|
||||
|
||||
+15
@@ -44,6 +44,18 @@ object LightTreePositioningStrategies {
|
||||
}
|
||||
}
|
||||
|
||||
val SUPERTYPES_LIST = object : LightTreePositioningStrategy() {
|
||||
override fun mark(
|
||||
node: LighterASTNode,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
tree: FlyweightCapableTreeStructure<LighterASTNode>
|
||||
): List<TextRange> {
|
||||
val target = tree.supertypesList(node) ?: node
|
||||
return markElement(target, startOffset, endOffset, tree, node)
|
||||
}
|
||||
}
|
||||
|
||||
val VAL_OR_VAR_NODE: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
|
||||
override fun mark(
|
||||
node: LighterASTNode,
|
||||
@@ -566,6 +578,9 @@ internal fun FlyweightCapableTreeStructure<LighterASTNode>.modalityModifier(decl
|
||||
internal fun FlyweightCapableTreeStructure<LighterASTNode>.overrideModifier(declaration: LighterASTNode): LighterASTNode? =
|
||||
modifierList(declaration)?.let { findChildByType(it, KtTokens.OVERRIDE_KEYWORD) }
|
||||
|
||||
private fun FlyweightCapableTreeStructure<LighterASTNode>.supertypesList(node: LighterASTNode): LighterASTNode? =
|
||||
findChildByType(node, KtNodeTypes.SUPER_TYPE_LIST)
|
||||
|
||||
private fun FlyweightCapableTreeStructure<LighterASTNode>.accessorNamePlaceholder(node: LighterASTNode): LighterASTNode =
|
||||
findChildByType(node, KtTokens.GET_KEYWORD) ?: findChildByType(node, KtTokens.SET_KEYWORD)!!
|
||||
|
||||
|
||||
+5
@@ -128,6 +128,11 @@ object SourceElementPositioningStrategies {
|
||||
PositioningStrategies.VALUE_ARGUMENTS
|
||||
)
|
||||
|
||||
val SUPERTYPES_LIST = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.SUPERTYPES_LIST,
|
||||
PositioningStrategies.SUPERTYPES_LIST
|
||||
)
|
||||
|
||||
val DOT_BY_QUALIFIED = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.DOT_BY_QUALIFIED,
|
||||
PositioningStrategies.DOT_BY_QUALIFIED
|
||||
|
||||
@@ -67,6 +67,20 @@ object PositioningStrategies {
|
||||
}
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val SUPERTYPES_LIST: PositioningStrategy<PsiElement> = object : PositioningStrategy<PsiElement>() {
|
||||
override fun mark(element: PsiElement): List<TextRange> {
|
||||
val supertypes = ((
|
||||
element as? KtClass
|
||||
) ?: return markElement(element)
|
||||
).superTypeListEntries
|
||||
return if (supertypes.isEmpty())
|
||||
markElement(element)
|
||||
else
|
||||
markRange(supertypes[0], supertypes.last())
|
||||
}
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val DECLARATION_RETURN_TYPE: PositioningStrategy<KtDeclaration> = object : PositioningStrategy<KtDeclaration>() {
|
||||
override fun mark(element: KtDeclaration): List<TextRange> {
|
||||
|
||||
+4
-4
@@ -2,7 +2,7 @@ val a = object: T {}
|
||||
open class C
|
||||
interface T
|
||||
|
||||
annotation class Ann: C()
|
||||
annotation class Ann2: T
|
||||
annotation class Ann3: T by <!ANNOTATION_CLASS_MEMBER!>a<!>
|
||||
annotation class Ann4: C(), T
|
||||
annotation class Ann: <!SUPERTYPES_FOR_ANNOTATION_CLASS!>C()<!>
|
||||
annotation class Ann2: <!SUPERTYPES_FOR_ANNOTATION_CLASS!>T<!>
|
||||
annotation class Ann3: <!SUPERTYPES_FOR_ANNOTATION_CLASS!>T by <!ANNOTATION_CLASS_MEMBER!>a<!><!>
|
||||
annotation class Ann4: <!SUPERTYPES_FOR_ANNOTATION_CLASS!>C(), T<!>
|
||||
|
||||
@@ -9,4 +9,4 @@ open class Your {
|
||||
open val x: Int = 0
|
||||
}
|
||||
|
||||
annotation class His(override val x: Int): Your()
|
||||
annotation class His(override val x: Int): <!SUPERTYPES_FOR_ANNOTATION_CLASS!>Your()<!>
|
||||
|
||||
Reference in New Issue
Block a user