FIR: add OptIn checkers draft + some annotation / SinceKotlin utilities
This commit is contained in:
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
|
||||||
import kotlin.contracts.*
|
import kotlin.contracts.*
|
||||||
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
|||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
|
||||||
import kotlin.contracts.*
|
import kotlin.contracts.*
|
||||||
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
|||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
|
||||||
import kotlin.contracts.*
|
import kotlin.contracts.*
|
||||||
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
|||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
|
||||||
import kotlin.contracts.*
|
import kotlin.contracts.*
|
||||||
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
|||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
|
||||||
import kotlin.contracts.*
|
import kotlin.contracts.*
|
||||||
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
|||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
|
||||||
import kotlin.contracts.*
|
import kotlin.contracts.*
|
||||||
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
|||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
|
||||||
import kotlin.contracts.*
|
import kotlin.contracts.*
|
||||||
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
|||||||
+31
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.*
|
|||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
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.resolve.ForbiddenNamedArgumentsTarget
|
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
||||||
@@ -212,6 +213,36 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val INAPPLICABLE_FILE_TARGET by error<KtAnnotationEntry>(PositioningStrategy.ANNOTATION_USE_SITE)
|
val INAPPLICABLE_FILE_TARGET by error<KtAnnotationEntry>(PositioningStrategy.ANNOTATION_USE_SITE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val EXPERIMENTAL by object : DiagnosticGroup("OptIn-related") {
|
||||||
|
val EXPERIMENTAL_API_USAGE by warning<PsiElement>(PositioningStrategy.REFERENCE_BY_QUALIFIED) {
|
||||||
|
parameter<FqName>("optInMarkerFqName")
|
||||||
|
parameter<String>("message")
|
||||||
|
}
|
||||||
|
val EXPERIMENTAL_API_USAGE_ERROR by error<PsiElement>(PositioningStrategy.REFERENCE_BY_QUALIFIED) {
|
||||||
|
parameter<FqName>("optInMarkerFqName")
|
||||||
|
parameter<String>("message")
|
||||||
|
}
|
||||||
|
val EXPERIMENTAL_OVERRIDE by warning<PsiElement> {
|
||||||
|
parameter<FqName>("optInMarkerFqName")
|
||||||
|
parameter<String>("message")
|
||||||
|
}
|
||||||
|
val EXPERIMENTAL_OVERRIDE_ERROR by error<PsiElement> {
|
||||||
|
parameter<FqName>("optInMarkerFqName")
|
||||||
|
parameter<String>("message")
|
||||||
|
}
|
||||||
|
val EXPERIMENTAL_IS_NOT_ENABLED by warning<KtAnnotationEntry>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
|
val EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION by error<PsiElement>()
|
||||||
|
val EXPERIMENTAL_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_USE_EXPERIMENTAL by error<PsiElement>()
|
||||||
|
val USE_EXPERIMENTAL_WITHOUT_ARGUMENTS by warning<KtAnnotationEntry>()
|
||||||
|
val USE_EXPERIMENTAL_ARGUMENT_IS_NOT_MARKER by warning<KtAnnotationEntry> {
|
||||||
|
parameter<FqName>("notMarkerFqName")
|
||||||
|
}
|
||||||
|
val EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET by error<KtAnnotationEntry> {
|
||||||
|
parameter<String>("target")
|
||||||
|
}
|
||||||
|
val EXPERIMENTAL_ANNOTATION_WITH_WRONG_RETENTION by error<KtAnnotationEntry>()
|
||||||
|
}
|
||||||
|
|
||||||
val EXPOSED_VISIBILITY by object : DiagnosticGroup("Exposed visibility") {
|
val EXPOSED_VISIBILITY by object : DiagnosticGroup("Exposed visibility") {
|
||||||
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by exposedVisibilityError<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME)
|
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by exposedVisibilityError<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME)
|
||||||
val EXPOSED_FUNCTION_RETURN_TYPE by exposedVisibilityError<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME)
|
val EXPOSED_FUNCTION_RETURN_TYPE by exposedVisibilityError<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME)
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
|||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotation
|
import org.jetbrains.kotlin.psi.KtAnnotation
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
@@ -200,6 +201,19 @@ object FirErrors {
|
|||||||
val REDUNDANT_ANNOTATION_TARGET by warning1<KtAnnotationEntry, String>()
|
val REDUNDANT_ANNOTATION_TARGET by warning1<KtAnnotationEntry, String>()
|
||||||
val INAPPLICABLE_FILE_TARGET by error0<KtAnnotationEntry>(SourceElementPositioningStrategies.ANNOTATION_USE_SITE)
|
val INAPPLICABLE_FILE_TARGET by error0<KtAnnotationEntry>(SourceElementPositioningStrategies.ANNOTATION_USE_SITE)
|
||||||
|
|
||||||
|
// OptIn-related
|
||||||
|
val EXPERIMENTAL_API_USAGE by warning2<PsiElement, FqName, String>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
|
val EXPERIMENTAL_API_USAGE_ERROR by error2<PsiElement, FqName, String>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||||
|
val EXPERIMENTAL_OVERRIDE by warning2<PsiElement, FqName, String>()
|
||||||
|
val EXPERIMENTAL_OVERRIDE_ERROR by error2<PsiElement, FqName, String>()
|
||||||
|
val EXPERIMENTAL_IS_NOT_ENABLED by warning0<KtAnnotationEntry>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
|
val EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION by error0<PsiElement>()
|
||||||
|
val EXPERIMENTAL_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_USE_EXPERIMENTAL by error0<PsiElement>()
|
||||||
|
val USE_EXPERIMENTAL_WITHOUT_ARGUMENTS by warning0<KtAnnotationEntry>()
|
||||||
|
val USE_EXPERIMENTAL_ARGUMENT_IS_NOT_MARKER by warning1<KtAnnotationEntry, FqName>()
|
||||||
|
val EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET by error1<KtAnnotationEntry, String>()
|
||||||
|
val EXPERIMENTAL_ANNOTATION_WITH_WRONG_RETENTION by error0<KtAnnotationEntry>()
|
||||||
|
|
||||||
// Exposed visibility
|
// Exposed visibility
|
||||||
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3<KtNamedDeclaration, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3<KtNamedDeclaration, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||||
val EXPOSED_FUNCTION_RETURN_TYPE by error3<KtNamedDeclaration, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
val EXPOSED_FUNCTION_RETURN_TYPE by error3<KtNamedDeclaration, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||||
|
|||||||
+1
@@ -71,6 +71,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
|||||||
override val regularClassCheckers: Set<FirRegularClassChecker>
|
override val regularClassCheckers: Set<FirRegularClassChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirAnnotationClassDeclarationChecker,
|
FirAnnotationClassDeclarationChecker,
|
||||||
|
FirOptInAnnotationClassChecker,
|
||||||
FirCommonConstructorDelegationIssuesChecker,
|
FirCommonConstructorDelegationIssuesChecker,
|
||||||
FirConstructorInInterfaceChecker,
|
FirConstructorInInterfaceChecker,
|
||||||
FirDelegationSuperCallInEnumConstructorChecker,
|
FirDelegationSuperCallInEnumConstructorChecker,
|
||||||
|
|||||||
+1
@@ -12,6 +12,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
|||||||
override val annotationCallCheckers: Set<FirAnnotationCallChecker>
|
override val annotationCallCheckers: Set<FirAnnotationCallChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirAnnotationArgumentChecker,
|
FirAnnotationArgumentChecker,
|
||||||
|
FirOptInAnnotationCallChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val basicExpressionCheckers: Set<FirBasicExpressionChecker>
|
override val basicExpressionCheckers: Set<FirBasicExpressionChecker>
|
||||||
|
|||||||
+21
-7
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||||
|
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirAnnotatedDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirAnnotatedDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
@@ -14,6 +15,7 @@ import org.jetbrains.kotlin.fir.expressions.*
|
|||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
@@ -49,11 +51,7 @@ fun FirAnnotationCall.getAllowedAnnotationTargets(session: FirSession): Set<Kotl
|
|||||||
fun FirRegularClass.getAllowedAnnotationTargets(): Set<KotlinTarget> {
|
fun FirRegularClass.getAllowedAnnotationTargets(): Set<KotlinTarget> {
|
||||||
val targetAnnotation = getTargetAnnotation() ?: return defaultAnnotationTargets
|
val targetAnnotation = getTargetAnnotation() ?: return defaultAnnotationTargets
|
||||||
if (targetAnnotation.argumentList.arguments.isEmpty()) return emptySet()
|
if (targetAnnotation.argumentList.arguments.isEmpty()) return emptySet()
|
||||||
val arguments = when (val targetArgument = targetAnnotation.findSingleArgumentByName(TARGET_PARAMETER_NAME)) {
|
val arguments = targetAnnotation.findSingleArgumentByName(TARGET_PARAMETER_NAME)?.unfoldArrayOrVararg().orEmpty()
|
||||||
is FirVarargArgumentsExpression -> targetArgument.arguments
|
|
||||||
is FirArrayOfCall -> targetArgument.arguments
|
|
||||||
else -> return defaultAnnotationTargets
|
|
||||||
}
|
|
||||||
|
|
||||||
return arguments.mapNotNullTo(mutableSetOf()) { argument ->
|
return arguments.mapNotNullTo(mutableSetOf()) { argument ->
|
||||||
val targetExpression = argument as? FirQualifiedAccessExpression
|
val targetExpression = argument as? FirQualifiedAccessExpression
|
||||||
@@ -70,7 +68,7 @@ fun FirAnnotatedDeclaration.getTargetAnnotation(): FirAnnotationCall? {
|
|||||||
return getAnnotationByFqName(StandardNames.FqNames.target)
|
return getAnnotationByFqName(StandardNames.FqNames.target)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirAnnotatedDeclaration.getAnnotationByFqName(fqName: FqName): FirAnnotationCall? {
|
fun FirAnnotationContainer.getAnnotationByFqName(fqName: FqName): FirAnnotationCall? {
|
||||||
return annotations.find {
|
return annotations.find {
|
||||||
(it.annotationTypeRef.coneType as? ConeClassLikeType)?.lookupTag?.classId?.asSingleFqName() == fqName
|
(it.annotationTypeRef.coneType as? ConeClassLikeType)?.lookupTag?.classId?.asSingleFqName() == fqName
|
||||||
}
|
}
|
||||||
@@ -79,7 +77,7 @@ fun FirAnnotatedDeclaration.getAnnotationByFqName(fqName: FqName): FirAnnotation
|
|||||||
fun FirAnnotationCall.findSingleArgumentByName(name: Name): FirExpression? {
|
fun FirAnnotationCall.findSingleArgumentByName(name: Name): FirExpression? {
|
||||||
val argumentMapping = argumentMapping
|
val argumentMapping = argumentMapping
|
||||||
if (argumentMapping != null) {
|
if (argumentMapping != null) {
|
||||||
return argumentMapping.keys.firstOrNull()?.takeIf { argumentMapping[it]?.name == name }
|
return argumentMapping.keys.firstOrNull()?.takeIf { argumentMapping[it]?.name == name }?.unwrapArgument()
|
||||||
}
|
}
|
||||||
// NB: we have to consider both cases, because deserializer does not create argument mapping
|
// NB: we have to consider both cases, because deserializer does not create argument mapping
|
||||||
val arguments = argumentList.arguments
|
val arguments = argumentList.arguments
|
||||||
@@ -87,3 +85,19 @@ fun FirAnnotationCall.findSingleArgumentByName(name: Name): FirExpression? {
|
|||||||
return firstArgument.takeIf { it.name == name }?.expression
|
return firstArgument.takeIf { it.name == name }?.expression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun FirExpression.extractClassesFromArgument(): List<FirRegularClassSymbol> {
|
||||||
|
return unfoldArrayOrVararg().mapNotNull {
|
||||||
|
if (it !is FirGetClassCall) return@mapNotNull null
|
||||||
|
val qualifier = it.argument as? FirResolvedQualifier ?: return@mapNotNull null
|
||||||
|
qualifier.symbol as? FirRegularClassSymbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirExpression.unfoldArrayOrVararg(): List<FirExpression> {
|
||||||
|
return when (this) {
|
||||||
|
is FirVarargArgumentsExpression -> arguments
|
||||||
|
is FirArrayOfCall -> arguments
|
||||||
|
else -> return emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+98
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.analysis.checkers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.config.ApiVersion
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirAnnotatedDeclaration
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.arguments
|
||||||
|
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
|
import org.jetbrains.kotlin.resolve.SINCE_KOTLIN_FQ_NAME
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||||
|
|
||||||
|
sealed class FirSinceKotlinAccessibility {
|
||||||
|
object Accessible : FirSinceKotlinAccessibility()
|
||||||
|
|
||||||
|
data class NotAccessibleButWasExperimental(
|
||||||
|
val version: ApiVersion,
|
||||||
|
val markerClasses: List<FirRegularClassSymbol>
|
||||||
|
) : FirSinceKotlinAccessibility()
|
||||||
|
|
||||||
|
data class NotAccessible(
|
||||||
|
val version: ApiVersion
|
||||||
|
) : FirSinceKotlinAccessibility()
|
||||||
|
}
|
||||||
|
|
||||||
|
private data class FirSinceKotlinValue(
|
||||||
|
val apiVersion: ApiVersion,
|
||||||
|
val wasExperimentalMarkerClasses: List<FirRegularClassSymbol>
|
||||||
|
)
|
||||||
|
|
||||||
|
fun FirAnnotatedDeclaration.checkSinceKotlinVersionAccessibility(context: CheckerContext): FirSinceKotlinAccessibility {
|
||||||
|
val value = getOwnSinceKotlinVersion(context.session)
|
||||||
|
val version = value?.apiVersion
|
||||||
|
val languageVersionSettings = context.session.languageVersionSettings
|
||||||
|
|
||||||
|
// Allow access in the following cases:
|
||||||
|
// 1) There's no @SinceKotlin annotation for this descriptor
|
||||||
|
// 2) There's a @SinceKotlin annotation but its value is some unrecognizable nonsense
|
||||||
|
// 3) The value as a version is not greater than our API version
|
||||||
|
if (version == null || version <= languageVersionSettings.apiVersion) return FirSinceKotlinAccessibility.Accessible
|
||||||
|
|
||||||
|
val wasExperimentalFqNames = value.wasExperimentalMarkerClasses
|
||||||
|
if (wasExperimentalFqNames.isNotEmpty()) {
|
||||||
|
return FirSinceKotlinAccessibility.NotAccessibleButWasExperimental(version, wasExperimentalFqNames)
|
||||||
|
}
|
||||||
|
|
||||||
|
return FirSinceKotlinAccessibility.NotAccessible(version)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirAnnotatedDeclaration.getOwnSinceKotlinVersion(session: FirSession): FirSinceKotlinValue? {
|
||||||
|
var result: FirSinceKotlinValue? = null
|
||||||
|
|
||||||
|
// TODO: use-site targeted annotations
|
||||||
|
fun FirAnnotatedDeclaration.consider() {
|
||||||
|
val sinceKotlinSingleArgument = getAnnotationByFqName(SINCE_KOTLIN_FQ_NAME)?.arguments?.singleOrNull()
|
||||||
|
val apiVersion = ((sinceKotlinSingleArgument as? FirConstExpression<*>)?.value as? String)?.let(ApiVersion.Companion::parse)
|
||||||
|
if (apiVersion != null) {
|
||||||
|
// TODO: combine wasExperimentalMarkerClasses in case of several associated declarations with the same maximal API version
|
||||||
|
if (result == null || apiVersion > result!!.apiVersion) {
|
||||||
|
result = FirSinceKotlinValue(apiVersion, loadWasExperimentalMarkerClasses())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.consider()
|
||||||
|
if (this is FirConstructor) {
|
||||||
|
val classId = symbol.callableId.classId
|
||||||
|
if (classId != null) {
|
||||||
|
val classSymbol = session.symbolProvider.getClassLikeSymbolByFqName(classId)
|
||||||
|
classSymbol?.fir?.consider()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this is FirTypeAlias) {
|
||||||
|
(this.expandedTypeRef.coneType as? ConeClassLikeType)?.lookupTag?.toSymbol(session)?.fir?.consider()
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirAnnotatedDeclaration.loadWasExperimentalMarkerClasses(): List<FirRegularClassSymbol> {
|
||||||
|
val wasExperimental = getAnnotationByFqName(OptInNames.WAS_EXPERIMENTAL_FQ_NAME) ?: return emptyList()
|
||||||
|
val annotationClasses = wasExperimental.findSingleArgumentByName(OptInNames.WAS_EXPERIMENTAL_ANNOTATION_CLASS) ?: return emptyList()
|
||||||
|
return annotationClasses.extractClassesFromArgument()
|
||||||
|
}
|
||||||
|
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.*
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.Experimentality
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||||
|
|
||||||
|
object FirOptInAnnotationClassChecker : FirRegularClassChecker() {
|
||||||
|
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
if (declaration.classKind != ClassKind.ANNOTATION_CLASS) return
|
||||||
|
if (declaration.getAnnotationByFqName(OptInNames.REQUIRES_OPT_IN_FQ_NAME) == null) return
|
||||||
|
if (declaration.getRetention() == AnnotationRetention.SOURCE) {
|
||||||
|
val target = declaration.getRetentionAnnotation()
|
||||||
|
reporter.reportOn(target?.source, FirErrors.EXPERIMENTAL_ANNOTATION_WITH_WRONG_RETENTION, context)
|
||||||
|
|
||||||
|
}
|
||||||
|
val wrongTargets = declaration.getAllowedAnnotationTargets().intersect(Experimentality.WRONG_TARGETS_FOR_MARKER)
|
||||||
|
if (wrongTargets.isNotEmpty()) {
|
||||||
|
val target = declaration.getTargetAnnotation()
|
||||||
|
reporter.reportOn(
|
||||||
|
target?.source,
|
||||||
|
FirErrors.EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET,
|
||||||
|
wrongTargets.joinToString(transform = KotlinTarget::description),
|
||||||
|
context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-1
@@ -20,11 +20,19 @@ import org.jetbrains.kotlin.fir.scopes.impl.toConeType
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens.QUEST
|
import org.jetbrains.kotlin.lexer.KtTokens.QUEST
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||||
|
|
||||||
object FirClassLiteralChecker : FirGetClassCallChecker() {
|
object FirClassLiteralChecker : FirGetClassCallChecker() {
|
||||||
override fun check(expression: FirGetClassCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirGetClassCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val source = expression.source ?: return
|
val source = expression.source ?: return
|
||||||
if (source.kind is FirFakeSourceElementKind) return
|
if (source.kind is FirFakeSourceElementKind) return
|
||||||
|
val argument = expression.argument
|
||||||
|
if (argument is FirResolvedQualifier) {
|
||||||
|
val fqName = argument.classId?.asSingleFqName()
|
||||||
|
if (fqName in OptInNames.EXPERIMENTAL_FQ_NAMES || fqName in OptInNames.USE_EXPERIMENTAL_FQ_NAMES) {
|
||||||
|
reporter.reportOn(argument.source, FirErrors.EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Note that raw FIR drops marked nullability "?" in, e.g., `A?::class`, `A<T?>::class`, or `A<T?>?::class`.
|
// Note that raw FIR drops marked nullability "?" in, e.g., `A?::class`, `A<T?>::class`, or `A<T?>?::class`.
|
||||||
// That is, AST structures for those expressions have token type QUEST, whereas FIR element doesn't have any information about it.
|
// That is, AST structures for those expressions have token type QUEST, whereas FIR element doesn't have any information about it.
|
||||||
@@ -36,7 +44,6 @@ object FirClassLiteralChecker : FirGetClassCallChecker() {
|
|||||||
//
|
//
|
||||||
// Only the 2nd example is valid, and we want to check if token type QUEST doesn't exist at the same level as COLONCOLON.
|
// Only the 2nd example is valid, and we want to check if token type QUEST doesn't exist at the same level as COLONCOLON.
|
||||||
val markedNullable = source.getChild(QUEST, depth = 1) != null
|
val markedNullable = source.getChild(QUEST, depth = 1) != null
|
||||||
val argument = expression.argument
|
|
||||||
val isNullable = markedNullable ||
|
val isNullable = markedNullable ||
|
||||||
(argument as? FirResolvedQualifier)?.isNullableLHSForCallableReference == true ||
|
(argument as? FirResolvedQualifier)?.isNullableLHSForCallableReference == true ||
|
||||||
argument.typeRef.coneType.isMarkedNullable ||
|
argument.typeRef.coneType.isMarkedNullable ||
|
||||||
|
|||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.config.AnalysisFlags
|
||||||
|
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.extractClassesFromArgument
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.findSingleArgumentByName
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||||
|
|
||||||
|
object FirOptInAnnotationCallChecker : FirAnnotationCallChecker() {
|
||||||
|
override fun check(expression: FirAnnotationCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
val lookupTag = expression.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag ?: return
|
||||||
|
val fqName = lookupTag.classId.asSingleFqName()
|
||||||
|
val isMarker = fqName == OptInNames.REQUIRES_OPT_IN_FQ_NAME
|
||||||
|
val isOptIn = fqName == OptInNames.OPT_IN_FQ_NAME
|
||||||
|
if (isMarker || isOptIn) {
|
||||||
|
checkUsageOfKotlinExperimentalOrUseExperimental(expression.source, context, reporter)
|
||||||
|
if (isOptIn) {
|
||||||
|
val arguments = expression.arguments
|
||||||
|
if (arguments.isEmpty()) {
|
||||||
|
reporter.reportOn(expression.source, FirErrors.USE_EXPERIMENTAL_WITHOUT_ARGUMENTS, context)
|
||||||
|
} else {
|
||||||
|
val annotationClasses = expression.findSingleArgumentByName(OptInNames.USE_EXPERIMENTAL_ANNOTATION_CLASS)
|
||||||
|
for (classSymbol in annotationClasses?.extractClassesFromArgument().orEmpty()) {
|
||||||
|
with(FirOptInUsageBaseChecker) {
|
||||||
|
if (classSymbol.fir.loadExperimentalityForMarkerAnnotation() == null) {
|
||||||
|
reporter.reportOn(
|
||||||
|
expression.source,
|
||||||
|
FirErrors.USE_EXPERIMENTAL_ARGUMENT_IS_NOT_MARKER,
|
||||||
|
classSymbol.classId.asSingleFqName(),
|
||||||
|
context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkUsageOfKotlinExperimentalOrUseExperimental(
|
||||||
|
element: FirSourceElement?,
|
||||||
|
context: CheckerContext,
|
||||||
|
reporter: DiagnosticReporter
|
||||||
|
) {
|
||||||
|
val useExperimentalFqNames = context.session.languageVersionSettings.getFlag(AnalysisFlags.useExperimental)
|
||||||
|
if (OptInNames.REQUIRES_OPT_IN_FQ_NAME.asString() !in useExperimentalFqNames) {
|
||||||
|
reporter.reportOn(element, FirErrors.EXPERIMENTAL_IS_NOT_ENABLED, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.findSingleArgumentByName
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.getAnnotationByFqName
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.Experimentality
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||||
|
|
||||||
|
object FirOptInUsageBaseChecker {
|
||||||
|
internal fun FirRegularClass.loadExperimentalityForMarkerAnnotation(): Experimentality? {
|
||||||
|
val experimental = getAnnotationByFqName(OptInNames.REQUIRES_OPT_IN_FQ_NAME) ?: return null
|
||||||
|
|
||||||
|
val levelArgument = experimental.findSingleArgumentByName(LEVEL) as? FirQualifiedAccessExpression
|
||||||
|
val levelName = (levelArgument?.calleeReference as? FirResolvedNamedReference)?.name?.asString()
|
||||||
|
val level = OptInLevel.values().firstOrNull { it.name == levelName } ?: OptInLevel.DEFAULT
|
||||||
|
val message = (experimental.findSingleArgumentByName(MESSAGE) as? FirConstExpression<*>)?.value as? String
|
||||||
|
return Experimentality(symbol.classId.asSingleFqName(), level.severity, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val LEVEL = Name.identifier("level")
|
||||||
|
private val MESSAGE = Name.identifier("message")
|
||||||
|
|
||||||
|
private enum class OptInLevel(val severity: Experimentality.Severity) {
|
||||||
|
WARNING(Experimentality.Severity.WARNING),
|
||||||
|
ERROR(Experimentality.Severity.ERROR),
|
||||||
|
DEFAULT(Experimentality.DEFAULT_SEVERITY)
|
||||||
|
}
|
||||||
|
}
|
||||||
+53
-6
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.*
|
import org.jetbrains.kotlin.diagnostics.rendering.*
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.Renderers.RENDER_POSITION_VARIANCE
|
import org.jetbrains.kotlin.diagnostics.rendering.Renderers.RENDER_POSITION_VARIANCE
|
||||||
|
import org.jetbrains.kotlin.diagnostics.rendering.Renderers.STRING
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.AMBIGUOUS_CALLS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.AMBIGUOUS_CALLS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECLARATION_NAME
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECLARATION_NAME
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FIR
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FIR
|
||||||
@@ -117,6 +118,15 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_DELEGATE
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_LATEINIT_PROPERTY
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_LATEINIT_PROPERTY
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_PRIVATE_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_PRIVATE_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_PROPERTY_INITIALIZER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_PROPERTY_INITIALIZER
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPERIMENTAL_ANNOTATION_WITH_WRONG_RETENTION
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPERIMENTAL_API_USAGE
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPERIMENTAL_API_USAGE_ERROR
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPERIMENTAL_IS_NOT_ENABLED
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPERIMENTAL_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_USE_EXPERIMENTAL
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPERIMENTAL_OVERRIDE
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPERIMENTAL_OVERRIDE_ERROR
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPLICIT_DELEGATION_CALL_REQUIRED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPLICIT_DELEGATION_CALL_REQUIRED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_FUNCTION_RETURN_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_FUNCTION_RETURN_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_PARAMETER_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_PARAMETER_TYPE
|
||||||
@@ -336,6 +346,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_ELVIS
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_ELVIS_RIGHT_IS_NULL
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_ELVIS_RIGHT_IS_NULL
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_IS_CHECK
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_IS_CHECK
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_VARARG_ON_PARAMETER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_VARARG_ON_PARAMETER
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USE_EXPERIMENTAL_ARGUMENT_IS_NOT_MARKER
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USE_EXPERIMENTAL_WITHOUT_ARGUMENTS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_BE_CLONEABLE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_BE_CLONEABLE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_OR_VAR_ON_CATCH_PARAMETER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_OR_VAR_ON_CATCH_PARAMETER
|
||||||
@@ -363,7 +375,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_MODIFIER_TA
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_SETTER_PARAMETER_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_SETTER_PARAMETER_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_SETTER_RETURN_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_SETTER_RETURN_TYPE
|
||||||
import org.jetbrains.kotlin.resolve.VarianceConflictDiagnosticData
|
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
||||||
@@ -399,10 +410,10 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
|||||||
map.put(VARIABLE_EXPECTED, "Variable expected")
|
map.put(VARIABLE_EXPECTED, "Variable expected")
|
||||||
map.put(DELEGATION_IN_INTERFACE, "Interfaces cannot use delegation")
|
map.put(DELEGATION_IN_INTERFACE, "Interfaces cannot use delegation")
|
||||||
map.put(NESTED_CLASS_NOT_ALLOWED, "{0} is not allowed here", TO_STRING)
|
map.put(NESTED_CLASS_NOT_ALLOWED, "{0} is not allowed here", TO_STRING)
|
||||||
map.put(VAL_OR_VAR_ON_LOOP_PARAMETER, "''{0}'' on loop parameter is not allowed", TO_STRING);
|
map.put(VAL_OR_VAR_ON_LOOP_PARAMETER, "''{0}'' on loop parameter is not allowed", TO_STRING)
|
||||||
map.put(VAL_OR_VAR_ON_FUN_PARAMETER, "''{0}'' on function parameter is not allowed", TO_STRING);
|
map.put(VAL_OR_VAR_ON_FUN_PARAMETER, "''{0}'' on function parameter is not allowed", TO_STRING)
|
||||||
map.put(VAL_OR_VAR_ON_CATCH_PARAMETER, "''{0}'' on catch parameter is not allowed", TO_STRING);
|
map.put(VAL_OR_VAR_ON_CATCH_PARAMETER, "''{0}'' on catch parameter is not allowed", TO_STRING)
|
||||||
map.put(VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER, "''{0}'' on secondary constructor parameter is not allowed", TO_STRING);
|
map.put(VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER, "''{0}'' on secondary constructor parameter is not allowed", TO_STRING)
|
||||||
|
|
||||||
// Unresolved
|
// Unresolved
|
||||||
map.put(INVISIBLE_REFERENCE, "Symbol {0} is invisible", SYMBOL)
|
map.put(INVISIBLE_REFERENCE, "Symbol {0} is invisible", SYMBOL)
|
||||||
@@ -528,6 +539,36 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
|||||||
TO_STRING
|
TO_STRING
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// OptIn
|
||||||
|
map.put(EXPERIMENTAL_API_USAGE, "{1}", TO_STRING, STRING)
|
||||||
|
map.put(EXPERIMENTAL_API_USAGE_ERROR, "{1}", TO_STRING, STRING)
|
||||||
|
|
||||||
|
map.put(EXPERIMENTAL_OVERRIDE, "{1}", TO_STRING, STRING)
|
||||||
|
map.put(EXPERIMENTAL_OVERRIDE_ERROR, "{1}", TO_STRING, STRING)
|
||||||
|
|
||||||
|
map.put(EXPERIMENTAL_IS_NOT_ENABLED, "This class can only be used with the compiler argument '-Xopt-in=kotlin.RequiresOptIn'")
|
||||||
|
map.put(EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION, "This class can only be used as an annotation")
|
||||||
|
map.put(
|
||||||
|
EXPERIMENTAL_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_USE_EXPERIMENTAL,
|
||||||
|
"This class can only be used as an annotation or as an argument to @OptIn"
|
||||||
|
)
|
||||||
|
map.put(USE_EXPERIMENTAL_WITHOUT_ARGUMENTS, "@OptIn without any arguments has no effect")
|
||||||
|
map.put(
|
||||||
|
USE_EXPERIMENTAL_ARGUMENT_IS_NOT_MARKER,
|
||||||
|
"Annotation ''{0}'' is not an opt-in requirement marker, therefore its usage in @OptIn is ignored",
|
||||||
|
TO_STRING
|
||||||
|
)
|
||||||
|
map.put(
|
||||||
|
EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET,
|
||||||
|
"Opt-in requirement marker annotation cannot be used on the following code elements: {0}. Please remove these targets",
|
||||||
|
STRING
|
||||||
|
)
|
||||||
|
map.put(
|
||||||
|
EXPERIMENTAL_ANNOTATION_WITH_WRONG_RETENTION,
|
||||||
|
"Opt-in requirement marker annotation cannot be used with SOURCE retention. Please replace retention with BINARY"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
// Exposed visibility group // #
|
// Exposed visibility group // #
|
||||||
map.put(
|
map.put(
|
||||||
EXPOSED_TYPEALIAS_EXPANDED_TYPE,
|
EXPOSED_TYPEALIAS_EXPANDED_TYPE,
|
||||||
@@ -585,7 +626,13 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
|||||||
map.put(TYPE_MISMATCH, "Type mismatch: inferred type is {1} but {0} was expected", TO_STRING, TO_STRING)
|
map.put(TYPE_MISMATCH, "Type mismatch: inferred type is {1} but {0} was expected", TO_STRING, TO_STRING)
|
||||||
map.put(THROWABLE_TYPE_MISMATCH, "Throwable type mismatch: actual type is {0}", TO_STRING)
|
map.put(THROWABLE_TYPE_MISMATCH, "Throwable type mismatch: actual type is {0}", TO_STRING)
|
||||||
map.put(CONDITION_TYPE_MISMATCH, "Condition type mismatch: inferred type is {0} but Boolean was expected", TO_STRING)
|
map.put(CONDITION_TYPE_MISMATCH, "Condition type mismatch: inferred type is {0} but Boolean was expected", TO_STRING)
|
||||||
map.put(ARGUMENT_TYPE_MISMATCH, "Argument type mismatch: actual type is {1} but {0} was expected", RENDER_TYPE, RENDER_TYPE, NOT_RENDERED)
|
map.put(
|
||||||
|
ARGUMENT_TYPE_MISMATCH,
|
||||||
|
"Argument type mismatch: actual type is {1} but {0} was expected",
|
||||||
|
RENDER_TYPE,
|
||||||
|
RENDER_TYPE,
|
||||||
|
NOT_RENDERED
|
||||||
|
)
|
||||||
map.put(ASSIGNMENT_TYPE_MISMATCH, "Assignment type mismatch: actual type is {1} but {0} was expected", RENDER_TYPE, RENDER_TYPE)
|
map.put(ASSIGNMENT_TYPE_MISMATCH, "Assignment type mismatch: actual type is {1} but {0} was expected", RENDER_TYPE, RENDER_TYPE)
|
||||||
map.put(
|
map.put(
|
||||||
RESULT_TYPE_MISMATCH,
|
RESULT_TYPE_MISMATCH,
|
||||||
|
|||||||
+1
-10
@@ -33,15 +33,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention
|
|||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
class ExperimentalMarkerDeclarationAnnotationChecker(private val module: ModuleDescriptor) : AdditionalAnnotationChecker {
|
class ExperimentalMarkerDeclarationAnnotationChecker(private val module: ModuleDescriptor) : AdditionalAnnotationChecker {
|
||||||
companion object {
|
|
||||||
private val WRONG_TARGETS_FOR_MARKER = setOf(
|
|
||||||
KotlinTarget.EXPRESSION,
|
|
||||||
KotlinTarget.FILE,
|
|
||||||
KotlinTarget.TYPE,
|
|
||||||
KotlinTarget.TYPE_PARAMETER
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun checkEntries(
|
override fun checkEntries(
|
||||||
entries: List<KtAnnotationEntry>,
|
entries: List<KtAnnotationEntry>,
|
||||||
actualTargets: List<KotlinTarget>,
|
actualTargets: List<KotlinTarget>,
|
||||||
@@ -154,7 +145,7 @@ class ExperimentalMarkerDeclarationAnnotationChecker(private val module: ModuleD
|
|||||||
if (targetEntry != null) {
|
if (targetEntry != null) {
|
||||||
val (entry, descriptor) = targetEntry
|
val (entry, descriptor) = targetEntry
|
||||||
val allowedTargets = AnnotationChecker.loadAnnotationTargets(descriptor!!) ?: return
|
val allowedTargets = AnnotationChecker.loadAnnotationTargets(descriptor!!) ?: return
|
||||||
val wrongTargets = allowedTargets.intersect(WRONG_TARGETS_FOR_MARKER)
|
val wrongTargets = allowedTargets.intersect(Experimentality.WRONG_TARGETS_FOR_MARKER)
|
||||||
if (wrongTargets.isNotEmpty()) {
|
if (wrongTargets.isNotEmpty()) {
|
||||||
trace.report(
|
trace.report(
|
||||||
Errors.EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET.on(
|
Errors.EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET.on(
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
// FILE: api.kt
|
// FILE: api.kt
|
||||||
|
|
||||||
@RequiresOptIn
|
@<!EXPERIMENTAL_IS_NOT_ENABLED!>RequiresOptIn<!>
|
||||||
@Retention(AnnotationRetention.BINARY)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
annotation class Marker
|
annotation class Marker
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ fun use2() {
|
|||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(Marker::class)
|
@<!EXPERIMENTAL_IS_NOT_ENABLED!>OptIn<!>(Marker::class)
|
||||||
fun use3() {
|
fun use3() {
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -12,21 +12,21 @@ import kotlin.annotation.AnnotationTarget.*
|
|||||||
annotation class E1
|
annotation class E1
|
||||||
|
|
||||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||||
@Target(FILE)
|
<!EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET!>@Target(FILE)<!>
|
||||||
annotation class E2
|
annotation class E2
|
||||||
|
|
||||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||||
@Target(EXPRESSION)
|
<!EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET!>@Target(EXPRESSION)<!>
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
<!EXPERIMENTAL_ANNOTATION_WITH_WRONG_RETENTION!>@Retention(AnnotationRetention.SOURCE)<!>
|
||||||
annotation class E3
|
annotation class E3
|
||||||
|
|
||||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||||
@Target(TYPE_PARAMETER)
|
<!EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET!>@Target(TYPE_PARAMETER)<!>
|
||||||
@Retention(AnnotationRetention.BINARY)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
annotation class E3A
|
annotation class E3A
|
||||||
|
|
||||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||||
@Target(TYPE)
|
<!EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET!>@Target(TYPE)<!>
|
||||||
@Retention(AnnotationRetention.BINARY)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
annotation class E3B
|
annotation class E3B
|
||||||
|
|
||||||
|
|||||||
-9
@@ -1,9 +0,0 @@
|
|||||||
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
|
|
||||||
|
|
||||||
annotation class NotAMarker
|
|
||||||
|
|
||||||
@OptIn
|
|
||||||
fun f1() {}
|
|
||||||
|
|
||||||
@OptIn(NotAMarker::class)
|
|
||||||
fun f2() {}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
|
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
|
||||||
|
|
||||||
annotation class NotAMarker
|
annotation class NotAMarker
|
||||||
|
|||||||
+4
-4
@@ -35,10 +35,10 @@ fun f4(u: OptIn0 /* TODO */) {}
|
|||||||
annotation class VarargKClasses(vararg val k: KClass<*>)
|
annotation class VarargKClasses(vararg val k: KClass<*>)
|
||||||
|
|
||||||
@VarargKClasses(
|
@VarargKClasses(
|
||||||
RequiresOptIn::class,
|
<!EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION!>RequiresOptIn<!>::class,
|
||||||
OptIn::class,
|
<!EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION!>OptIn<!>::class,
|
||||||
kotlin.RequiresOptIn::class,
|
<!EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION!>kotlin.RequiresOptIn<!>::class,
|
||||||
kotlin.OptIn::class
|
<!EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION!>kotlin.OptIn<!>::class
|
||||||
)
|
)
|
||||||
fun f5() {}
|
fun f5() {}
|
||||||
|
|
||||||
|
|||||||
@@ -15,5 +15,5 @@ class A {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
|
@<!EXPERIMENTAL_IS_NOT_ENABLED!>RequiresOptIn<!>(level = RequiresOptIn.Level.ERROR)
|
||||||
annotation class ExperimentalTime
|
annotation class ExperimentalTime
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.checkers
|
package org.jetbrains.kotlin.resolve.checkers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
data class Experimentality(val annotationFqName: FqName, val severity: Severity, val message: String?) {
|
data class Experimentality(val annotationFqName: FqName, val severity: Severity, val message: String?) {
|
||||||
@@ -12,5 +13,12 @@ data class Experimentality(val annotationFqName: FqName, val severity: Severity,
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val DEFAULT_SEVERITY = Severity.ERROR
|
val DEFAULT_SEVERITY = Severity.ERROR
|
||||||
|
|
||||||
|
val WRONG_TARGETS_FOR_MARKER = setOf(
|
||||||
|
KotlinTarget.EXPRESSION,
|
||||||
|
KotlinTarget.FILE,
|
||||||
|
KotlinTarget.TYPE,
|
||||||
|
KotlinTarget.TYPE_PARAMETER
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
|||||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
||||||
@@ -252,7 +253,8 @@ private object FirToKtConversionCreator {
|
|||||||
ForbiddenNamedArgumentsTarget::class,
|
ForbiddenNamedArgumentsTarget::class,
|
||||||
LanguageFeature::class,
|
LanguageFeature::class,
|
||||||
LanguageVersionSettings::class,
|
LanguageVersionSettings::class,
|
||||||
Variance::class
|
Variance::class,
|
||||||
|
FqName::class,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val KType.kClass: KClass<*>
|
private val KType.kClass: KClass<*>
|
||||||
|
|||||||
+76
@@ -717,6 +717,82 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.EXPERIMENTAL_API_USAGE) { firDiagnostic ->
|
||||||
|
ExperimentalApiUsageImpl(
|
||||||
|
firDiagnostic.a,
|
||||||
|
firDiagnostic.b,
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirErrors.EXPERIMENTAL_API_USAGE_ERROR) { firDiagnostic ->
|
||||||
|
ExperimentalApiUsageErrorImpl(
|
||||||
|
firDiagnostic.a,
|
||||||
|
firDiagnostic.b,
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirErrors.EXPERIMENTAL_OVERRIDE) { firDiagnostic ->
|
||||||
|
ExperimentalOverrideImpl(
|
||||||
|
firDiagnostic.a,
|
||||||
|
firDiagnostic.b,
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirErrors.EXPERIMENTAL_OVERRIDE_ERROR) { firDiagnostic ->
|
||||||
|
ExperimentalOverrideErrorImpl(
|
||||||
|
firDiagnostic.a,
|
||||||
|
firDiagnostic.b,
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirErrors.EXPERIMENTAL_IS_NOT_ENABLED) { firDiagnostic ->
|
||||||
|
ExperimentalIsNotEnabledImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirErrors.EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION) { firDiagnostic ->
|
||||||
|
ExperimentalCanOnlyBeUsedAsAnnotationImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirErrors.EXPERIMENTAL_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_USE_EXPERIMENTAL) { firDiagnostic ->
|
||||||
|
ExperimentalMarkerCanOnlyBeUsedAsAnnotationOrArgumentInUseExperimentalImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirErrors.USE_EXPERIMENTAL_WITHOUT_ARGUMENTS) { firDiagnostic ->
|
||||||
|
UseExperimentalWithoutArgumentsImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirErrors.USE_EXPERIMENTAL_ARGUMENT_IS_NOT_MARKER) { firDiagnostic ->
|
||||||
|
UseExperimentalArgumentIsNotMarkerImpl(
|
||||||
|
firDiagnostic.a,
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirErrors.EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET) { firDiagnostic ->
|
||||||
|
ExperimentalAnnotationWithWrongTargetImpl(
|
||||||
|
firDiagnostic.a,
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirErrors.EXPERIMENTAL_ANNOTATION_WITH_WRONG_RETENTION) { firDiagnostic ->
|
||||||
|
ExperimentalAnnotationWithWrongRetentionImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE) { firDiagnostic ->
|
add(FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE) { firDiagnostic ->
|
||||||
ExposedTypealiasExpandedTypeImpl(
|
ExposedTypealiasExpandedTypeImpl(
|
||||||
firDiagnostic.a,
|
firDiagnostic.a,
|
||||||
|
|||||||
+55
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableSymbol
|
|||||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotation
|
import org.jetbrains.kotlin.psi.KtAnnotation
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
@@ -513,6 +514,60 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = InapplicableFileTarget::class
|
override val diagnosticClass get() = InapplicableFileTarget::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class ExperimentalApiUsage : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = ExperimentalApiUsage::class
|
||||||
|
abstract val optInMarkerFqName: FqName
|
||||||
|
abstract val message: String
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ExperimentalApiUsageError : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = ExperimentalApiUsageError::class
|
||||||
|
abstract val optInMarkerFqName: FqName
|
||||||
|
abstract val message: String
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ExperimentalOverride : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = ExperimentalOverride::class
|
||||||
|
abstract val optInMarkerFqName: FqName
|
||||||
|
abstract val message: String
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ExperimentalOverrideError : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = ExperimentalOverrideError::class
|
||||||
|
abstract val optInMarkerFqName: FqName
|
||||||
|
abstract val message: String
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ExperimentalIsNotEnabled : KtFirDiagnostic<KtAnnotationEntry>() {
|
||||||
|
override val diagnosticClass get() = ExperimentalIsNotEnabled::class
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ExperimentalCanOnlyBeUsedAsAnnotation : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = ExperimentalCanOnlyBeUsedAsAnnotation::class
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ExperimentalMarkerCanOnlyBeUsedAsAnnotationOrArgumentInUseExperimental : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = ExperimentalMarkerCanOnlyBeUsedAsAnnotationOrArgumentInUseExperimental::class
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class UseExperimentalWithoutArguments : KtFirDiagnostic<KtAnnotationEntry>() {
|
||||||
|
override val diagnosticClass get() = UseExperimentalWithoutArguments::class
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class UseExperimentalArgumentIsNotMarker : KtFirDiagnostic<KtAnnotationEntry>() {
|
||||||
|
override val diagnosticClass get() = UseExperimentalArgumentIsNotMarker::class
|
||||||
|
abstract val notMarkerFqName: FqName
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ExperimentalAnnotationWithWrongTarget : KtFirDiagnostic<KtAnnotationEntry>() {
|
||||||
|
override val diagnosticClass get() = ExperimentalAnnotationWithWrongTarget::class
|
||||||
|
abstract val target: String
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ExperimentalAnnotationWithWrongRetention : KtFirDiagnostic<KtAnnotationEntry>() {
|
||||||
|
override val diagnosticClass get() = ExperimentalAnnotationWithWrongRetention::class
|
||||||
|
}
|
||||||
|
|
||||||
abstract class ExposedTypealiasExpandedType : KtFirDiagnostic<KtNamedDeclaration>() {
|
abstract class ExposedTypealiasExpandedType : KtFirDiagnostic<KtNamedDeclaration>() {
|
||||||
override val diagnosticClass get() = ExposedTypealiasExpandedType::class
|
override val diagnosticClass get() = ExposedTypealiasExpandedType::class
|
||||||
abstract val elementVisibility: EffectiveVisibility
|
abstract val elementVisibility: EffectiveVisibility
|
||||||
|
|||||||
+88
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
|||||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotation
|
import org.jetbrains.kotlin.psi.KtAnnotation
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
@@ -832,6 +833,93 @@ internal class InapplicableFileTargetImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class ExperimentalApiUsageImpl(
|
||||||
|
override val optInMarkerFqName: FqName,
|
||||||
|
override val message: String,
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.ExperimentalApiUsage(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ExperimentalApiUsageErrorImpl(
|
||||||
|
override val optInMarkerFqName: FqName,
|
||||||
|
override val message: String,
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.ExperimentalApiUsageError(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ExperimentalOverrideImpl(
|
||||||
|
override val optInMarkerFqName: FqName,
|
||||||
|
override val message: String,
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.ExperimentalOverride(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ExperimentalOverrideErrorImpl(
|
||||||
|
override val optInMarkerFqName: FqName,
|
||||||
|
override val message: String,
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.ExperimentalOverrideError(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ExperimentalIsNotEnabledImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.ExperimentalIsNotEnabled(), KtAbstractFirDiagnostic<KtAnnotationEntry> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ExperimentalCanOnlyBeUsedAsAnnotationImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.ExperimentalCanOnlyBeUsedAsAnnotation(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ExperimentalMarkerCanOnlyBeUsedAsAnnotationOrArgumentInUseExperimentalImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.ExperimentalMarkerCanOnlyBeUsedAsAnnotationOrArgumentInUseExperimental(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class UseExperimentalWithoutArgumentsImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.UseExperimentalWithoutArguments(), KtAbstractFirDiagnostic<KtAnnotationEntry> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class UseExperimentalArgumentIsNotMarkerImpl(
|
||||||
|
override val notMarkerFqName: FqName,
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.UseExperimentalArgumentIsNotMarker(), KtAbstractFirDiagnostic<KtAnnotationEntry> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ExperimentalAnnotationWithWrongTargetImpl(
|
||||||
|
override val target: String,
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.ExperimentalAnnotationWithWrongTarget(), KtAbstractFirDiagnostic<KtAnnotationEntry> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ExperimentalAnnotationWithWrongRetentionImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.ExperimentalAnnotationWithWrongRetention(), KtAbstractFirDiagnostic<KtAnnotationEntry> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
internal class ExposedTypealiasExpandedTypeImpl(
|
internal class ExposedTypealiasExpandedTypeImpl(
|
||||||
override val elementVisibility: EffectiveVisibility,
|
override val elementVisibility: EffectiveVisibility,
|
||||||
override val restrictingDeclaration: KtSymbol,
|
override val restrictingDeclaration: KtSymbol,
|
||||||
|
|||||||
Reference in New Issue
Block a user