Restore KtModifierKeywordToken instead of String in modifier diagnostics
Remove KeywordType
This commit is contained in:
committed by
TeamCityServer
parent
a8077aebb0
commit
301f446433
+14
-14
@@ -301,35 +301,35 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val MODIFIERS by object : DiagnosticGroup("Modifiers") {
|
val MODIFIERS by object : DiagnosticGroup("Modifiers") {
|
||||||
val INAPPLICABLE_INFIX_MODIFIER by error<PsiElement>()
|
val INAPPLICABLE_INFIX_MODIFIER by error<PsiElement>()
|
||||||
val REPEATED_MODIFIER by error<PsiElement> {
|
val REPEATED_MODIFIER by error<PsiElement> {
|
||||||
parameter<String>("modifier")
|
parameter<KtModifierKeywordToken>("modifier")
|
||||||
}
|
}
|
||||||
val REDUNDANT_MODIFIER by error<PsiElement> {
|
val REDUNDANT_MODIFIER by error<PsiElement> {
|
||||||
parameter<String>("redundantModifier")
|
parameter<KtModifierKeywordToken>("redundantModifier")
|
||||||
parameter<String>("conflictingModifier")
|
parameter<KtModifierKeywordToken>("conflictingModifier")
|
||||||
}
|
}
|
||||||
val DEPRECATED_MODIFIER by warning<PsiElement> {
|
val DEPRECATED_MODIFIER by warning<PsiElement> {
|
||||||
parameter<String>("deprecatedModifier")
|
parameter<KtModifierKeywordToken>("deprecatedModifier")
|
||||||
parameter<String>("actualModifier")
|
parameter<KtModifierKeywordToken>("actualModifier")
|
||||||
}
|
}
|
||||||
val DEPRECATED_MODIFIER_PAIR by error<PsiElement> {
|
val DEPRECATED_MODIFIER_PAIR by error<PsiElement> {
|
||||||
parameter<String>("deprecatedModifier")
|
parameter<KtModifierKeywordToken>("deprecatedModifier")
|
||||||
parameter<String>("conflictingModifier")
|
parameter<KtModifierKeywordToken>("conflictingModifier")
|
||||||
}
|
}
|
||||||
val DEPRECATED_MODIFIER_FOR_TARGET by warning<PsiElement> {
|
val DEPRECATED_MODIFIER_FOR_TARGET by warning<PsiElement> {
|
||||||
parameter<String>("deprecatedModifier")
|
parameter<KtModifierKeywordToken>("deprecatedModifier")
|
||||||
parameter<String>("target")
|
parameter<String>("target")
|
||||||
}
|
}
|
||||||
val REDUNDANT_MODIFIER_FOR_TARGET by warning<PsiElement> {
|
val REDUNDANT_MODIFIER_FOR_TARGET by warning<PsiElement> {
|
||||||
parameter<String>("redundantModifier")
|
parameter<KtModifierKeywordToken>("redundantModifier")
|
||||||
parameter<String>("target")
|
parameter<String>("target")
|
||||||
}
|
}
|
||||||
val INCOMPATIBLE_MODIFIERS by error<PsiElement> {
|
val INCOMPATIBLE_MODIFIERS by error<PsiElement> {
|
||||||
parameter<String>("modifier1")
|
parameter<KtModifierKeywordToken>("modifier1")
|
||||||
parameter<String>("modifier2")
|
parameter<KtModifierKeywordToken>("modifier2")
|
||||||
}
|
}
|
||||||
val REDUNDANT_OPEN_IN_INTERFACE by warning<KtModifierListOwner>(PositioningStrategy.OPEN_MODIFIER)
|
val REDUNDANT_OPEN_IN_INTERFACE by warning<KtModifierListOwner>(PositioningStrategy.OPEN_MODIFIER)
|
||||||
val WRONG_MODIFIER_TARGET by error<PsiElement> {
|
val WRONG_MODIFIER_TARGET by error<PsiElement> {
|
||||||
parameter<String>("modifier")
|
parameter<KtModifierKeywordToken>("modifier")
|
||||||
parameter<String>("target")
|
parameter<String>("target")
|
||||||
}
|
}
|
||||||
val OPERATOR_MODIFIER_REQUIRED by error<PsiElement> {
|
val OPERATOR_MODIFIER_REQUIRED by error<PsiElement> {
|
||||||
@@ -340,11 +340,11 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
parameter<FirNamedFunctionSymbol>("functionSymbol")
|
parameter<FirNamedFunctionSymbol>("functionSymbol")
|
||||||
}
|
}
|
||||||
val WRONG_MODIFIER_CONTAINING_DECLARATION by error<PsiElement> {
|
val WRONG_MODIFIER_CONTAINING_DECLARATION by error<PsiElement> {
|
||||||
parameter<String>("modifier")
|
parameter<KtModifierKeywordToken>("modifier")
|
||||||
parameter<String>("target")
|
parameter<String>("target")
|
||||||
}
|
}
|
||||||
val DEPRECATED_MODIFIER_CONTAINING_DECLARATION by warning<PsiElement> {
|
val DEPRECATED_MODIFIER_CONTAINING_DECLARATION by warning<PsiElement> {
|
||||||
parameter<String>("modifier")
|
parameter<KtModifierKeywordToken>("modifier")
|
||||||
parameter<String>("target")
|
parameter<String>("target")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ object FirJvmExternalDeclarationChecker : FirBasicDeclarationChecker() {
|
|||||||
}
|
}
|
||||||
val externalModifier = declaration.getModifier(KtTokens.EXTERNAL_KEYWORD)
|
val externalModifier = declaration.getModifier(KtTokens.EXTERNAL_KEYWORD)
|
||||||
externalModifier?.let {
|
externalModifier?.let {
|
||||||
reporter.reportOn(it.source, FirErrors.WRONG_MODIFIER_TARGET, it.token.toString(), target, context)
|
reporter.reportOn(it.source, FirErrors.WRONG_MODIFIER_TARGET, it.token, target, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-10
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
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.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
@@ -254,19 +255,19 @@ object FirErrors {
|
|||||||
|
|
||||||
// Modifiers
|
// Modifiers
|
||||||
val INAPPLICABLE_INFIX_MODIFIER by error0<PsiElement>()
|
val INAPPLICABLE_INFIX_MODIFIER by error0<PsiElement>()
|
||||||
val REPEATED_MODIFIER by error1<PsiElement, String>()
|
val REPEATED_MODIFIER by error1<PsiElement, KtModifierKeywordToken>()
|
||||||
val REDUNDANT_MODIFIER by error2<PsiElement, String, String>()
|
val REDUNDANT_MODIFIER by error2<PsiElement, KtModifierKeywordToken, KtModifierKeywordToken>()
|
||||||
val DEPRECATED_MODIFIER by warning2<PsiElement, String, String>()
|
val DEPRECATED_MODIFIER by warning2<PsiElement, KtModifierKeywordToken, KtModifierKeywordToken>()
|
||||||
val DEPRECATED_MODIFIER_PAIR by error2<PsiElement, String, String>()
|
val DEPRECATED_MODIFIER_PAIR by error2<PsiElement, KtModifierKeywordToken, KtModifierKeywordToken>()
|
||||||
val DEPRECATED_MODIFIER_FOR_TARGET by warning2<PsiElement, String, String>()
|
val DEPRECATED_MODIFIER_FOR_TARGET by warning2<PsiElement, KtModifierKeywordToken, String>()
|
||||||
val REDUNDANT_MODIFIER_FOR_TARGET by warning2<PsiElement, String, String>()
|
val REDUNDANT_MODIFIER_FOR_TARGET by warning2<PsiElement, KtModifierKeywordToken, String>()
|
||||||
val INCOMPATIBLE_MODIFIERS by error2<PsiElement, String, String>()
|
val INCOMPATIBLE_MODIFIERS by error2<PsiElement, KtModifierKeywordToken, KtModifierKeywordToken>()
|
||||||
val REDUNDANT_OPEN_IN_INTERFACE by warning0<KtModifierListOwner>(SourceElementPositioningStrategies.OPEN_MODIFIER)
|
val REDUNDANT_OPEN_IN_INTERFACE by warning0<KtModifierListOwner>(SourceElementPositioningStrategies.OPEN_MODIFIER)
|
||||||
val WRONG_MODIFIER_TARGET by error2<PsiElement, String, String>()
|
val WRONG_MODIFIER_TARGET by error2<PsiElement, KtModifierKeywordToken, String>()
|
||||||
val OPERATOR_MODIFIER_REQUIRED by error2<PsiElement, FirNamedFunctionSymbol, String>()
|
val OPERATOR_MODIFIER_REQUIRED by error2<PsiElement, FirNamedFunctionSymbol, String>()
|
||||||
val INFIX_MODIFIER_REQUIRED by error1<PsiElement, FirNamedFunctionSymbol>()
|
val INFIX_MODIFIER_REQUIRED by error1<PsiElement, FirNamedFunctionSymbol>()
|
||||||
val WRONG_MODIFIER_CONTAINING_DECLARATION by error2<PsiElement, String, String>()
|
val WRONG_MODIFIER_CONTAINING_DECLARATION by error2<PsiElement, KtModifierKeywordToken, String>()
|
||||||
val DEPRECATED_MODIFIER_CONTAINING_DECLARATION by warning2<PsiElement, String, String>()
|
val DEPRECATED_MODIFIER_CONTAINING_DECLARATION by warning2<PsiElement, KtModifierKeywordToken, String>()
|
||||||
|
|
||||||
// Inline classes
|
// Inline classes
|
||||||
val INLINE_CLASS_NOT_TOP_LEVEL by error0<KtDeclaration>(SourceElementPositioningStrategies.INLINE_OR_VALUE_MODIFIER)
|
val INLINE_CLASS_NOT_TOP_LEVEL by error0<KtDeclaration>(SourceElementPositioningStrategies.INLINE_OR_VALUE_MODIFIER)
|
||||||
|
|||||||
-51
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 licensedot/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.fir.analysis.checkers
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
|
||||||
import org.jetbrains.kotlin.resolve.KeywordType
|
|
||||||
|
|
||||||
fun getKeywordType(modifier: FirModifier<*>): KeywordType {
|
|
||||||
return ktKeywordToKeywordTypeMap[modifier.token]!!
|
|
||||||
}
|
|
||||||
|
|
||||||
private val ktKeywordToKeywordTypeMap: Map<KtKeywordToken, KeywordType> = mapOf(
|
|
||||||
INNER_KEYWORD to KeywordType.Inner,
|
|
||||||
OVERRIDE_KEYWORD to KeywordType.Override,
|
|
||||||
PUBLIC_KEYWORD to KeywordType.Public,
|
|
||||||
PROTECTED_KEYWORD to KeywordType.Protected,
|
|
||||||
INTERNAL_KEYWORD to KeywordType.Internal,
|
|
||||||
PRIVATE_KEYWORD to KeywordType.Private,
|
|
||||||
COMPANION_KEYWORD to KeywordType.Companion,
|
|
||||||
FINAL_KEYWORD to KeywordType.Final,
|
|
||||||
VARARG_KEYWORD to KeywordType.Vararg,
|
|
||||||
ENUM_KEYWORD to KeywordType.Enum,
|
|
||||||
ABSTRACT_KEYWORD to KeywordType.Abstract,
|
|
||||||
OPEN_KEYWORD to KeywordType.Open,
|
|
||||||
SEALED_KEYWORD to KeywordType.Sealed,
|
|
||||||
IN_KEYWORD to KeywordType.In,
|
|
||||||
OUT_KEYWORD to KeywordType.Out,
|
|
||||||
REIFIED_KEYWORD to KeywordType.Reified,
|
|
||||||
LATEINIT_KEYWORD to KeywordType.Lateinit,
|
|
||||||
DATA_KEYWORD to KeywordType.Data,
|
|
||||||
INLINE_KEYWORD to KeywordType.Inline,
|
|
||||||
NOINLINE_KEYWORD to KeywordType.Noinline,
|
|
||||||
TAILREC_KEYWORD to KeywordType.Tailrec,
|
|
||||||
SUSPEND_KEYWORD to KeywordType.Suspend,
|
|
||||||
EXTERNAL_KEYWORD to KeywordType.External,
|
|
||||||
ANNOTATION_KEYWORD to KeywordType.Annotation,
|
|
||||||
CROSSINLINE_KEYWORD to KeywordType.Crossinline,
|
|
||||||
CONST_KEYWORD to KeywordType.Const,
|
|
||||||
OPERATOR_KEYWORD to KeywordType.Operator,
|
|
||||||
INFIX_KEYWORD to KeywordType.Infix,
|
|
||||||
HEADER_KEYWORD to KeywordType.Header,
|
|
||||||
IMPL_KEYWORD to KeywordType.Impl,
|
|
||||||
EXPECT_KEYWORD to KeywordType.Expect,
|
|
||||||
ACTUAL_KEYWORD to KeywordType.Actual,
|
|
||||||
FUN_KEYWORD to KeywordType.Fun,
|
|
||||||
VALUE_KEYWORD to KeywordType.Value
|
|
||||||
)
|
|
||||||
+1
-1
@@ -29,7 +29,7 @@ object FirConstPropertyChecker : FirPropertyChecker() {
|
|||||||
if (declaration.isVar) {
|
if (declaration.isVar) {
|
||||||
val constModifier = declaration.getModifier(KtTokens.CONST_KEYWORD)
|
val constModifier = declaration.getModifier(KtTokens.CONST_KEYWORD)
|
||||||
constModifier?.let {
|
constModifier?.let {
|
||||||
reporter.reportOn(it.source, FirErrors.WRONG_MODIFIER_TARGET, it.token.toString(), "vars", context)
|
reporter.reportOn(it.source, FirErrors.WRONG_MODIFIER_TARGET, it.token, "vars", context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+35
-33
@@ -23,6 +23,8 @@ import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
|
|||||||
import org.jetbrains.kotlin.fir.declarations.utils.isInner
|
import org.jetbrains.kotlin.fir.declarations.utils.isInner
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.resolve.*
|
import org.jetbrains.kotlin.resolve.*
|
||||||
|
|
||||||
object FirModifierChecker : FirBasicDeclarationChecker() {
|
object FirModifierChecker : FirBasicDeclarationChecker() {
|
||||||
@@ -87,10 +89,10 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
|||||||
}
|
}
|
||||||
if (secondModifier !in reportedNodes) {
|
if (secondModifier !in reportedNodes) {
|
||||||
val modifierSource = secondModifier.source
|
val modifierSource = secondModifier.source
|
||||||
val modifierType = getKeywordType(secondModifier)
|
val modifier = secondModifier.token
|
||||||
when {
|
when {
|
||||||
!checkTarget(modifierSource, modifierType, actualTargets, parent, context, reporter) -> reportedNodes += secondModifier
|
!checkTarget(modifierSource, modifier, actualTargets, parent, context, reporter) -> reportedNodes += secondModifier
|
||||||
!checkParent(modifierSource, modifierType, actualParents, context, reporter) -> reportedNodes += secondModifier
|
!checkParent(modifierSource, modifier, actualParents, context, reporter) -> reportedNodes += secondModifier
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,21 +106,21 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
|||||||
owner: FirDeclaration?,
|
owner: FirDeclaration?,
|
||||||
context: CheckerContext
|
context: CheckerContext
|
||||||
) {
|
) {
|
||||||
val firstModifierType = getKeywordType(firstModifier)
|
val firstModifierToken = firstModifier.token
|
||||||
val secondModifierType = getKeywordType(secondModifier)
|
val secondModifierToken = secondModifier.token
|
||||||
when (val compatibilityType = compatibility(firstModifierType, secondModifierType)) {
|
when (val compatibilityType = compatibility(firstModifierToken, secondModifierToken)) {
|
||||||
Compatibility.COMPATIBLE -> {
|
Compatibility.COMPATIBLE -> {
|
||||||
}
|
}
|
||||||
Compatibility.REPEATED ->
|
Compatibility.REPEATED ->
|
||||||
if (reportedNodes.add(secondModifier)) {
|
if (reportedNodes.add(secondModifier)) {
|
||||||
reporter.reportOn(secondModifier.source, FirErrors.REPEATED_MODIFIER, secondModifierType.render(), context)
|
reporter.reportOn(secondModifier.source, FirErrors.REPEATED_MODIFIER, secondModifierToken, context)
|
||||||
}
|
}
|
||||||
Compatibility.REDUNDANT -> {
|
Compatibility.REDUNDANT -> {
|
||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
secondModifier.source,
|
secondModifier.source,
|
||||||
FirErrors.REDUNDANT_MODIFIER,
|
FirErrors.REDUNDANT_MODIFIER,
|
||||||
secondModifierType.render(),
|
secondModifierToken,
|
||||||
firstModifierType.render(),
|
firstModifierToken,
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -126,8 +128,8 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
|||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
firstModifier.source,
|
firstModifier.source,
|
||||||
FirErrors.REDUNDANT_MODIFIER,
|
FirErrors.REDUNDANT_MODIFIER,
|
||||||
firstModifierType.render(),
|
firstModifierToken,
|
||||||
secondModifierType.render(),
|
secondModifierToken,
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -135,15 +137,15 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
|||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
firstModifier.source,
|
firstModifier.source,
|
||||||
FirErrors.DEPRECATED_MODIFIER_PAIR,
|
FirErrors.DEPRECATED_MODIFIER_PAIR,
|
||||||
firstModifierType.render(),
|
firstModifierToken,
|
||||||
secondModifierType.render(),
|
secondModifierToken,
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
secondModifier.source,
|
secondModifier.source,
|
||||||
FirErrors.DEPRECATED_MODIFIER_PAIR,
|
FirErrors.DEPRECATED_MODIFIER_PAIR,
|
||||||
secondModifierType.render(),
|
secondModifierToken,
|
||||||
firstModifierType.render(),
|
firstModifierToken,
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -155,8 +157,8 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
|||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
firstModifier.source,
|
firstModifier.source,
|
||||||
FirErrors.INCOMPATIBLE_MODIFIERS,
|
FirErrors.INCOMPATIBLE_MODIFIERS,
|
||||||
firstModifierType.render(),
|
firstModifierToken,
|
||||||
secondModifierType.render(),
|
secondModifierToken,
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -164,8 +166,8 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
|||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
secondModifier.source,
|
secondModifier.source,
|
||||||
FirErrors.INCOMPATIBLE_MODIFIERS,
|
FirErrors.INCOMPATIBLE_MODIFIERS,
|
||||||
secondModifierType.render(),
|
secondModifierToken,
|
||||||
firstModifierType.render(),
|
firstModifierToken,
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -175,19 +177,19 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
|||||||
|
|
||||||
private fun checkTarget(
|
private fun checkTarget(
|
||||||
modifierSource: FirSourceElement,
|
modifierSource: FirSourceElement,
|
||||||
modifierType: KeywordType,
|
modifierToken: KtModifierKeywordToken,
|
||||||
actualTargets: List<KotlinTarget>,
|
actualTargets: List<KotlinTarget>,
|
||||||
parent: FirDeclaration?,
|
parent: FirDeclaration?,
|
||||||
context: CheckerContext,
|
context: CheckerContext,
|
||||||
reporter: DiagnosticReporter
|
reporter: DiagnosticReporter
|
||||||
): Boolean {
|
): Boolean {
|
||||||
fun checkModifier(factory: FirDiagnosticFactory2<String, String>): Boolean {
|
fun checkModifier(factory: FirDiagnosticFactory2<KtModifierKeywordToken, String>): Boolean {
|
||||||
val map = when (factory) {
|
val map = when (factory) {
|
||||||
FirErrors.WRONG_MODIFIER_TARGET -> possibleTargetMap
|
FirErrors.WRONG_MODIFIER_TARGET -> possibleTargetMap
|
||||||
FirErrors.DEPRECATED_MODIFIER_FOR_TARGET -> deprecatedTargetMap
|
FirErrors.DEPRECATED_MODIFIER_FOR_TARGET -> deprecatedTargetMap
|
||||||
else -> redundantTargetMap
|
else -> redundantTargetMap
|
||||||
}
|
}
|
||||||
val set = map[modifierType] ?: emptySet()
|
val set = map[modifierToken] ?: emptySet()
|
||||||
val checkResult = if (factory == FirErrors.WRONG_MODIFIER_TARGET) {
|
val checkResult = if (factory == FirErrors.WRONG_MODIFIER_TARGET) {
|
||||||
actualTargets.none { it in set }
|
actualTargets.none { it in set }
|
||||||
} else {
|
} else {
|
||||||
@@ -197,7 +199,7 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
|||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
modifierSource,
|
modifierSource,
|
||||||
factory,
|
factory,
|
||||||
modifierType.render(),
|
modifierToken,
|
||||||
actualTargets.firstOrThis(),
|
actualTargets.firstOrThis(),
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
@@ -211,19 +213,19 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (parent is FirRegularClass) {
|
if (parent is FirRegularClass) {
|
||||||
if (modifierType == KeywordType.Expect || modifierType == KeywordType.Header) {
|
if (modifierToken == KtTokens.EXPECT_KEYWORD || modifierToken == KtTokens.HEADER_KEYWORD) {
|
||||||
reporter.reportOn(modifierSource, FirErrors.WRONG_MODIFIER_TARGET, modifierType.render(), "nested class", context)
|
reporter.reportOn(modifierSource, FirErrors.WRONG_MODIFIER_TARGET, modifierToken, "nested class", context)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val deprecatedModifierReplacement = deprecatedModifierMap[modifierType]
|
val deprecatedModifierReplacement = deprecatedModifierMap[modifierToken]
|
||||||
if (deprecatedModifierReplacement != null) {
|
if (deprecatedModifierReplacement != null) {
|
||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
modifierSource,
|
modifierSource,
|
||||||
FirErrors.DEPRECATED_MODIFIER,
|
FirErrors.DEPRECATED_MODIFIER,
|
||||||
modifierType.render(),
|
modifierToken,
|
||||||
deprecatedModifierReplacement.render(),
|
deprecatedModifierReplacement,
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
} else if (checkModifier(FirErrors.DEPRECATED_MODIFIER_FOR_TARGET)) {
|
} else if (checkModifier(FirErrors.DEPRECATED_MODIFIER_FOR_TARGET)) {
|
||||||
@@ -235,30 +237,30 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
|
|||||||
|
|
||||||
private fun checkParent(
|
private fun checkParent(
|
||||||
modifierSource: FirSourceElement,
|
modifierSource: FirSourceElement,
|
||||||
modifierType: KeywordType,
|
modifierToken: KtModifierKeywordToken,
|
||||||
actualParents: List<KotlinTarget>,
|
actualParents: List<KotlinTarget>,
|
||||||
context: CheckerContext,
|
context: CheckerContext,
|
||||||
reporter: DiagnosticReporter
|
reporter: DiagnosticReporter
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val deprecatedParents = deprecatedParentTargetMap[modifierType]
|
val deprecatedParents = deprecatedParentTargetMap[modifierToken]
|
||||||
if (deprecatedParents != null && actualParents.any { it in deprecatedParents }) {
|
if (deprecatedParents != null && actualParents.any { it in deprecatedParents }) {
|
||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
modifierSource,
|
modifierSource,
|
||||||
FirErrors.DEPRECATED_MODIFIER_CONTAINING_DECLARATION,
|
FirErrors.DEPRECATED_MODIFIER_CONTAINING_DECLARATION,
|
||||||
modifierType.render(),
|
modifierToken,
|
||||||
actualParents.firstOrThis(),
|
actualParents.firstOrThis(),
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
val possibleParentPredicate = possibleParentTargetPredicateMap[modifierType] ?: return true
|
val possibleParentPredicate = possibleParentTargetPredicateMap[modifierToken] ?: return true
|
||||||
if (actualParents.any { possibleParentPredicate.isAllowed(it, context.session.languageVersionSettings) }) return true
|
if (actualParents.any { possibleParentPredicate.isAllowed(it, context.session.languageVersionSettings) }) return true
|
||||||
|
|
||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
modifierSource,
|
modifierSource,
|
||||||
FirErrors.WRONG_MODIFIER_CONTAINING_DECLARATION,
|
FirErrors.WRONG_MODIFIER_CONTAINING_DECLARATION,
|
||||||
modifierType.render(),
|
modifierToken,
|
||||||
actualParents.firstOrThis(),
|
actualParents.firstOrThis(),
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@ object FirSuspendModifierChecker : FirTypeRefChecker() {
|
|||||||
reporter.reportOn(
|
reporter.reportOn(
|
||||||
suspendModifier.source,
|
suspendModifier.source,
|
||||||
FirErrors.WRONG_MODIFIER_TARGET,
|
FirErrors.WRONG_MODIFIER_TARGET,
|
||||||
suspendModifier.token.toString(),
|
suspendModifier.token,
|
||||||
"non-functional type",
|
"non-functional type",
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
|
|||||||
+10
-10
@@ -732,18 +732,18 @@ class FirDefaultErrorMessages {
|
|||||||
|
|
||||||
// Modifiers
|
// Modifiers
|
||||||
map.put(INAPPLICABLE_INFIX_MODIFIER, "''infix'' modifier is inapplicable on this function")
|
map.put(INAPPLICABLE_INFIX_MODIFIER, "''infix'' modifier is inapplicable on this function")
|
||||||
map.put(REPEATED_MODIFIER, "Repeated ''{0}''", STRING)
|
map.put(REPEATED_MODIFIER, "Repeated ''{0}''", TO_STRING)
|
||||||
map.put(REDUNDANT_MODIFIER, "Modifier ''{0}'' is redundant because ''{1}'' is present", STRING, STRING)
|
map.put(REDUNDANT_MODIFIER, "Modifier ''{0}'' is redundant because ''{1}'' is present", TO_STRING, TO_STRING)
|
||||||
map.put(DEPRECATED_MODIFIER, "Modifier ''{0}'' is deprecated, use ''{1}'' instead", STRING, STRING)
|
map.put(DEPRECATED_MODIFIER, "Modifier ''{0}'' is deprecated, use ''{1}'' instead", TO_STRING, TO_STRING)
|
||||||
map.put(DEPRECATED_MODIFIER_PAIR, "Modifier ''{0}'' is deprecated in presence of ''{1}''", STRING, STRING)
|
map.put(DEPRECATED_MODIFIER_PAIR, "Modifier ''{0}'' is deprecated in presence of ''{1}''", TO_STRING, TO_STRING)
|
||||||
map.put(DEPRECATED_MODIFIER_FOR_TARGET, "Modifier ''{0}'' is deprecated for ''{1}''", STRING, STRING)
|
map.put(DEPRECATED_MODIFIER_FOR_TARGET, "Modifier ''{0}'' is deprecated for ''{1}''", TO_STRING, STRING)
|
||||||
map.put(REDUNDANT_MODIFIER_FOR_TARGET, "Modifier ''{0}'' is redundant for ''{1}''", STRING, STRING)
|
map.put(REDUNDANT_MODIFIER_FOR_TARGET, "Modifier ''{0}'' is redundant for ''{1}''", TO_STRING, STRING)
|
||||||
map.put(INCOMPATIBLE_MODIFIERS, "Modifier ''{0}'' is incompatible with ''{1}''", STRING, STRING)
|
map.put(INCOMPATIBLE_MODIFIERS, "Modifier ''{0}'' is incompatible with ''{1}''", TO_STRING, TO_STRING)
|
||||||
map.put(REDUNDANT_OPEN_IN_INTERFACE, "Modifier 'open' is redundant for abstract interface members")
|
map.put(REDUNDANT_OPEN_IN_INTERFACE, "Modifier 'open' is redundant for abstract interface members")
|
||||||
map.put(WRONG_MODIFIER_TARGET, "Modifier ''{0}'' is not applicable to ''{1}''", STRING, STRING)
|
map.put(WRONG_MODIFIER_TARGET, "Modifier ''{0}'' is not applicable to ''{1}''", TO_STRING, STRING)
|
||||||
map.put(INFIX_MODIFIER_REQUIRED, "''infix'' modifier is required on ''{0}''", TO_STRING)
|
map.put(INFIX_MODIFIER_REQUIRED, "''infix'' modifier is required on ''{0}''", TO_STRING)
|
||||||
map.put(WRONG_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is not applicable inside ''{1}''", STRING, STRING)
|
map.put(WRONG_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is not applicable inside ''{1}''", TO_STRING, STRING)
|
||||||
map.put(DEPRECATED_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is deprecated inside ''{1}''", STRING, STRING)
|
map.put(DEPRECATED_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is deprecated inside ''{1}''", TO_STRING, STRING)
|
||||||
|
|
||||||
// Classes and interfaces
|
// Classes and interfaces
|
||||||
map.put(SUPERTYPE_NOT_INITIALIZED, "This type has a constructor, and thus must be initialized here")
|
map.put(SUPERTYPE_NOT_INITIALIZED, "This type has a constructor, and thus must be initialized here")
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ public interface Errors {
|
|||||||
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, KtModifierKeywordToken> REDUNDANT_MODIFIER = DiagnosticFactory2.create(WARNING);
|
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, KtModifierKeywordToken> REDUNDANT_MODIFIER = DiagnosticFactory2.create(WARNING);
|
||||||
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, String> WRONG_MODIFIER_TARGET = DiagnosticFactory2.create(ERROR);
|
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, String> WRONG_MODIFIER_TARGET = DiagnosticFactory2.create(ERROR);
|
||||||
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, String> DEPRECATED_MODIFIER_FOR_TARGET = DiagnosticFactory2.create(WARNING);
|
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, String> DEPRECATED_MODIFIER_FOR_TARGET = DiagnosticFactory2.create(WARNING);
|
||||||
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, String> DEPRECATED_MODIFIER = DiagnosticFactory2.create(WARNING);
|
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, KtModifierKeywordToken> DEPRECATED_MODIFIER = DiagnosticFactory2.create(WARNING);
|
||||||
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, String> REDUNDANT_MODIFIER_FOR_TARGET = DiagnosticFactory2.create(WARNING);
|
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, String> REDUNDANT_MODIFIER_FOR_TARGET = DiagnosticFactory2.create(WARNING);
|
||||||
DiagnosticFactory0<KtDeclaration> NO_EXPLICIT_VISIBILITY_IN_API_MODE = DiagnosticFactory0.create(ERROR, DECLARATION_START_TO_NAME);
|
DiagnosticFactory0<KtDeclaration> NO_EXPLICIT_VISIBILITY_IN_API_MODE = DiagnosticFactory0.create(ERROR, DECLARATION_START_TO_NAME);
|
||||||
DiagnosticFactory0<KtNamedDeclaration> NO_EXPLICIT_RETURN_TYPE_IN_API_MODE = DiagnosticFactory0.create(ERROR, DECLARATION_NAME);
|
DiagnosticFactory0<KtNamedDeclaration> NO_EXPLICIT_RETURN_TYPE_IN_API_MODE = DiagnosticFactory0.create(ERROR, DECLARATION_NAME);
|
||||||
|
|||||||
@@ -13,55 +13,15 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
|
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
|
||||||
import org.jetbrains.kotlin.psi.KtModifierList
|
import org.jetbrains.kotlin.psi.KtModifierList
|
||||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||||
import org.jetbrains.kotlin.resolve.KeywordType.*
|
|
||||||
import org.jetbrains.kotlin.resolve.KeywordType.Annotation
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.checkCoroutinesFeature
|
import org.jetbrains.kotlin.resolve.calls.checkers.checkCoroutinesFeature
|
||||||
|
|
||||||
object ModifierCheckerCore {
|
object ModifierCheckerCore {
|
||||||
private val ktKeywordToKeywordTypeMap: Map<KtKeywordToken, KeywordType> = mapOf(
|
|
||||||
INNER_KEYWORD to Inner,
|
|
||||||
OVERRIDE_KEYWORD to Override,
|
|
||||||
PUBLIC_KEYWORD to Public,
|
|
||||||
PROTECTED_KEYWORD to Protected,
|
|
||||||
INTERNAL_KEYWORD to Internal,
|
|
||||||
PRIVATE_KEYWORD to Private,
|
|
||||||
COMPANION_KEYWORD to KeywordType.Companion,
|
|
||||||
FINAL_KEYWORD to Final,
|
|
||||||
VARARG_KEYWORD to Vararg,
|
|
||||||
ENUM_KEYWORD to KeywordType.Enum,
|
|
||||||
ABSTRACT_KEYWORD to Abstract,
|
|
||||||
OPEN_KEYWORD to Open,
|
|
||||||
SEALED_KEYWORD to Sealed,
|
|
||||||
IN_KEYWORD to In,
|
|
||||||
OUT_KEYWORD to Out,
|
|
||||||
REIFIED_KEYWORD to Reified,
|
|
||||||
LATEINIT_KEYWORD to Lateinit,
|
|
||||||
DATA_KEYWORD to Data,
|
|
||||||
INLINE_KEYWORD to Inline,
|
|
||||||
NOINLINE_KEYWORD to Noinline,
|
|
||||||
TAILREC_KEYWORD to Tailrec,
|
|
||||||
SUSPEND_KEYWORD to Suspend,
|
|
||||||
EXTERNAL_KEYWORD to External,
|
|
||||||
ANNOTATION_KEYWORD to Annotation,
|
|
||||||
CROSSINLINE_KEYWORD to Crossinline,
|
|
||||||
CONST_KEYWORD to Const,
|
|
||||||
OPERATOR_KEYWORD to Operator,
|
|
||||||
INFIX_KEYWORD to Infix,
|
|
||||||
HEADER_KEYWORD to Header,
|
|
||||||
IMPL_KEYWORD to Impl,
|
|
||||||
EXPECT_KEYWORD to Expect,
|
|
||||||
ACTUAL_KEYWORD to Actual,
|
|
||||||
FUN_KEYWORD to Fun,
|
|
||||||
VALUE_KEYWORD to Value
|
|
||||||
)
|
|
||||||
|
|
||||||
fun check(
|
fun check(
|
||||||
listOwner: KtModifierListOwner,
|
listOwner: KtModifierListOwner,
|
||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
@@ -123,10 +83,9 @@ object ModifierCheckerCore {
|
|||||||
owner: PsiElement,
|
owner: PsiElement,
|
||||||
incorrectNodes: MutableSet<ASTNode>
|
incorrectNodes: MutableSet<ASTNode>
|
||||||
) {
|
) {
|
||||||
val (firstModifier, firstModifierType) = getModifierAndModifierType(firstNode)
|
val firstModifier = firstNode.elementType as KtModifierKeywordToken
|
||||||
val (secondModifier, secondModifierType) = getModifierAndModifierType(secondNode)
|
val secondModifier = secondNode.elementType as KtModifierKeywordToken
|
||||||
|
when (val compatibility = compatibility(firstModifier, secondModifier)) {
|
||||||
when (val compatibility = compatibility(firstModifierType, secondModifierType)) {
|
|
||||||
Compatibility.COMPATIBLE -> {
|
Compatibility.COMPATIBLE -> {
|
||||||
}
|
}
|
||||||
Compatibility.REPEATED -> if (incorrectNodes.add(secondNode)) {
|
Compatibility.REPEATED -> if (incorrectNodes.add(secondNode)) {
|
||||||
@@ -156,19 +115,19 @@ object ModifierCheckerCore {
|
|||||||
|
|
||||||
// Should return false if error is reported, true otherwise
|
// Should return false if error is reported, true otherwise
|
||||||
private fun checkTarget(trace: BindingTrace, node: ASTNode, actualTargets: List<KotlinTarget>): Boolean {
|
private fun checkTarget(trace: BindingTrace, node: ASTNode, actualTargets: List<KotlinTarget>): Boolean {
|
||||||
val (modifier, modifierType) = getModifierAndModifierType(node)
|
val modifier = node.elementType as KtModifierKeywordToken
|
||||||
|
|
||||||
val possibleTargets = possibleTargetMap[modifierType] ?: emptySet()
|
val possibleTargets = possibleTargetMap[modifier] ?: emptySet()
|
||||||
if (!actualTargets.any { it in possibleTargets }) {
|
if (!actualTargets.any { it in possibleTargets }) {
|
||||||
trace.report(Errors.WRONG_MODIFIER_TARGET.on(node.psi, modifier, actualTargets.firstOrNull()?.description ?: "this"))
|
trace.report(Errors.WRONG_MODIFIER_TARGET.on(node.psi, modifier, actualTargets.firstOrNull()?.description ?: "this"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val deprecatedModifierReplacement = deprecatedModifierMap[modifierType]
|
val deprecatedModifierReplacement = deprecatedModifierMap[modifier]
|
||||||
val deprecatedTargets = deprecatedTargetMap[modifierType] ?: emptySet()
|
val deprecatedTargets = deprecatedTargetMap[modifier] ?: emptySet()
|
||||||
val redundantTargets = redundantTargetMap[modifierType] ?: emptySet()
|
val redundantTargets = redundantTargetMap[modifier] ?: emptySet()
|
||||||
when {
|
when {
|
||||||
deprecatedModifierReplacement != null ->
|
deprecatedModifierReplacement != null ->
|
||||||
trace.report(Errors.DEPRECATED_MODIFIER.on(node.psi, modifier, deprecatedModifierReplacement.render()))
|
trace.report(Errors.DEPRECATED_MODIFIER.on(node.psi, modifier, deprecatedModifierReplacement))
|
||||||
actualTargets.any { it in deprecatedTargets } ->
|
actualTargets.any { it in deprecatedTargets } ->
|
||||||
trace.report(
|
trace.report(
|
||||||
Errors.DEPRECATED_MODIFIER_FOR_TARGET.on(
|
Errors.DEPRECATED_MODIFIER_FOR_TARGET.on(
|
||||||
@@ -196,7 +155,7 @@ object ModifierCheckerCore {
|
|||||||
parentDescriptor: DeclarationDescriptor?,
|
parentDescriptor: DeclarationDescriptor?,
|
||||||
languageVersionSettings: LanguageVersionSettings
|
languageVersionSettings: LanguageVersionSettings
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val (modifier, modifierType) = getModifierAndModifierType(node)
|
val modifier = node.elementType as KtModifierKeywordToken
|
||||||
|
|
||||||
val actualParents: List<KotlinTarget> = when (parentDescriptor) {
|
val actualParents: List<KotlinTarget> = when (parentDescriptor) {
|
||||||
is ClassDescriptor -> KotlinTarget.classActualTargets(
|
is ClassDescriptor -> KotlinTarget.classActualTargets(
|
||||||
@@ -210,7 +169,7 @@ object ModifierCheckerCore {
|
|||||||
is FunctionDescriptor -> KotlinTarget.FUNCTION_LIST
|
is FunctionDescriptor -> KotlinTarget.FUNCTION_LIST
|
||||||
else -> KotlinTarget.FILE_LIST
|
else -> KotlinTarget.FILE_LIST
|
||||||
}
|
}
|
||||||
val deprecatedParents = deprecatedParentTargetMap[modifierType]
|
val deprecatedParents = deprecatedParentTargetMap[modifier]
|
||||||
if (deprecatedParents != null && actualParents.any { it in deprecatedParents }) {
|
if (deprecatedParents != null && actualParents.any { it in deprecatedParents }) {
|
||||||
trace.report(
|
trace.report(
|
||||||
Errors.DEPRECATED_MODIFIER_CONTAINING_DECLARATION.on(
|
Errors.DEPRECATED_MODIFIER_CONTAINING_DECLARATION.on(
|
||||||
@@ -221,7 +180,7 @@ object ModifierCheckerCore {
|
|||||||
)
|
)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
val possibleParentPredicate = possibleParentTargetPredicateMap[modifierType] ?: return true
|
val possibleParentPredicate = possibleParentTargetPredicateMap[modifier] ?: return true
|
||||||
if (actualParents.any { possibleParentPredicate.isAllowed(it, languageVersionSettings) }) return true
|
if (actualParents.any { possibleParentPredicate.isAllowed(it, languageVersionSettings) }) return true
|
||||||
trace.report(
|
trace.report(
|
||||||
Errors.WRONG_MODIFIER_CONTAINING_DECLARATION.on(
|
Errors.WRONG_MODIFIER_CONTAINING_DECLARATION.on(
|
||||||
@@ -239,9 +198,9 @@ object ModifierCheckerCore {
|
|||||||
languageVersionSettings: LanguageVersionSettings,
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
actualTargets: List<KotlinTarget>
|
actualTargets: List<KotlinTarget>
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val (_, modifierType) = getModifierAndModifierType(node)
|
val modifier = node.elementType as KtModifierKeywordToken
|
||||||
|
|
||||||
val dependencies = featureDependencies[modifierType] ?: return true
|
val dependencies = featureDependencies[modifier] ?: return true
|
||||||
for (dependency in dependencies) {
|
for (dependency in dependencies) {
|
||||||
val restrictedTargets = featureDependenciesTargets[dependency]
|
val restrictedTargets = featureDependenciesTargets[dependency]
|
||||||
if (restrictedTargets != null && actualTargets.intersect(restrictedTargets).isEmpty()) {
|
if (restrictedTargets != null && actualTargets.intersect(restrictedTargets).isEmpty()) {
|
||||||
@@ -282,9 +241,4 @@ object ModifierCheckerCore {
|
|||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getModifierAndModifierType(node: ASTNode): Pair<KtModifierKeywordToken, KeywordType> {
|
|
||||||
val modifier = node.elementType as KtModifierKeywordToken
|
|
||||||
return Pair(modifier, ktKeywordToKeywordTypeMap[modifier]!!)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,366 @@
|
|||||||
|
/*
|
||||||
|
* 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.resolve
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||||
|
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
enum class Compatibility {
|
||||||
|
// modifier pair is compatible: ok (default)
|
||||||
|
COMPATIBLE,
|
||||||
|
|
||||||
|
// second is redundant to first: warning
|
||||||
|
REDUNDANT,
|
||||||
|
|
||||||
|
// first is redundant to second: warning
|
||||||
|
REVERSE_REDUNDANT,
|
||||||
|
|
||||||
|
// error
|
||||||
|
REPEATED,
|
||||||
|
|
||||||
|
// pair is deprecated, will become incompatible: warning
|
||||||
|
DEPRECATED,
|
||||||
|
|
||||||
|
// pair is incompatible: error
|
||||||
|
INCOMPATIBLE,
|
||||||
|
|
||||||
|
// same but only for functions / properties: error
|
||||||
|
COMPATIBLE_FOR_CLASSES_ONLY
|
||||||
|
}
|
||||||
|
|
||||||
|
val compatibilityTypeMap = hashMapOf<Pair<KtKeywordToken, KtKeywordToken>, Compatibility>()
|
||||||
|
|
||||||
|
fun compatibility(first: KtKeywordToken, second: KtKeywordToken): Compatibility {
|
||||||
|
return if (first == second) {
|
||||||
|
Compatibility.REPEATED
|
||||||
|
} else {
|
||||||
|
mutualCompatibility[Pair(first, second)] ?: Compatibility.COMPATIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// First modifier in pair should be also first in declaration
|
||||||
|
private val mutualCompatibility = buildCompatibilityMap()
|
||||||
|
|
||||||
|
private fun buildCompatibilityMap(): Map<Pair<KtKeywordToken, KtKeywordToken>, Compatibility> {
|
||||||
|
val result = hashMapOf<Pair<KtKeywordToken, KtKeywordToken>, Compatibility>()
|
||||||
|
// Variance: in + out are incompatible
|
||||||
|
result += incompatibilityRegister(IN_KEYWORD, OUT_KEYWORD)
|
||||||
|
// Visibilities: incompatible
|
||||||
|
result += incompatibilityRegister(PRIVATE_KEYWORD, PROTECTED_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD)
|
||||||
|
// Abstract + open + final + sealed: incompatible
|
||||||
|
result += incompatibilityRegister(ABSTRACT_KEYWORD, OPEN_KEYWORD, FINAL_KEYWORD, SEALED_KEYWORD)
|
||||||
|
// data + open, data + inner, data + abstract, data + sealed, data + inline, data + value
|
||||||
|
result += incompatibilityRegister(DATA_KEYWORD, OPEN_KEYWORD)
|
||||||
|
result += incompatibilityRegister(DATA_KEYWORD, INNER_KEYWORD)
|
||||||
|
result += incompatibilityRegister(DATA_KEYWORD, ABSTRACT_KEYWORD)
|
||||||
|
result += incompatibilityRegister(DATA_KEYWORD, SEALED_KEYWORD)
|
||||||
|
result += incompatibilityRegister(DATA_KEYWORD, INLINE_KEYWORD)
|
||||||
|
result += incompatibilityRegister(DATA_KEYWORD, VALUE_KEYWORD)
|
||||||
|
// open is redundant to abstract & override
|
||||||
|
result += redundantRegister(ABSTRACT_KEYWORD, OPEN_KEYWORD)
|
||||||
|
// abstract is redundant to sealed
|
||||||
|
result += redundantRegister(SEALED_KEYWORD, ABSTRACT_KEYWORD)
|
||||||
|
|
||||||
|
// const is incompatible with abstract, open, override
|
||||||
|
result += incompatibilityRegister(CONST_KEYWORD, ABSTRACT_KEYWORD)
|
||||||
|
result += incompatibilityRegister(CONST_KEYWORD, OPEN_KEYWORD)
|
||||||
|
result += incompatibilityRegister(CONST_KEYWORD, OVERRIDE_KEYWORD)
|
||||||
|
|
||||||
|
// private is incompatible with override
|
||||||
|
result += incompatibilityRegister(PRIVATE_KEYWORD, OVERRIDE_KEYWORD)
|
||||||
|
// private is compatible with open / abstract only for classes
|
||||||
|
result += compatibilityForClassesRegister(PRIVATE_KEYWORD, OPEN_KEYWORD)
|
||||||
|
result += compatibilityForClassesRegister(PRIVATE_KEYWORD, ABSTRACT_KEYWORD)
|
||||||
|
|
||||||
|
result += incompatibilityRegister(CROSSINLINE_KEYWORD, NOINLINE_KEYWORD)
|
||||||
|
|
||||||
|
// 1. subclasses contained inside a sealed class can not be instantiated, because their constructors needs
|
||||||
|
// an instance of an outer sealed (effectively abstract) class
|
||||||
|
// 2. subclasses of a non-top-level sealed class must be declared inside the class
|
||||||
|
// (see the KEEP https://github.com/Kotlin/KEEP/blob/master/proposals/sealed-class-inheritance.md)
|
||||||
|
result += incompatibilityRegister(SEALED_KEYWORD, INNER_KEYWORD)
|
||||||
|
|
||||||
|
// header / expect / impl / actual are all incompatible
|
||||||
|
result += incompatibilityRegister(HEADER_KEYWORD, EXPECT_KEYWORD, IMPL_KEYWORD, ACTUAL_KEYWORD)
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun incompatibilityRegister(vararg list: KtKeywordToken): Map<Pair<KtKeywordToken, KtKeywordToken>, Compatibility> {
|
||||||
|
return compatibilityRegister(Compatibility.INCOMPATIBLE, *list)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun redundantRegister(
|
||||||
|
sufficient: KtKeywordToken,
|
||||||
|
redundant: KtKeywordToken
|
||||||
|
): Map<Pair<KtKeywordToken, KtKeywordToken>, Compatibility> {
|
||||||
|
return mapOf(
|
||||||
|
Pair(sufficient, redundant) to Compatibility.REDUNDANT,
|
||||||
|
Pair(redundant, sufficient) to Compatibility.REVERSE_REDUNDANT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun compatibilityForClassesRegister(vararg list: KtKeywordToken) =
|
||||||
|
compatibilityRegister(Compatibility.COMPATIBLE_FOR_CLASSES_ONLY, *list)
|
||||||
|
|
||||||
|
private fun compatibilityRegister(
|
||||||
|
compatibility: Compatibility, vararg list: KtKeywordToken
|
||||||
|
): Map<Pair<KtKeywordToken, KtKeywordToken>, Compatibility> {
|
||||||
|
val result = hashMapOf<Pair<KtKeywordToken, KtKeywordToken>, Compatibility>()
|
||||||
|
for (first in list) {
|
||||||
|
for (second in list) {
|
||||||
|
if (first != second) {
|
||||||
|
result[Pair(first, second)] = compatibility
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
val featureDependencies = mapOf(
|
||||||
|
SUSPEND_KEYWORD to listOf(LanguageFeature.Coroutines),
|
||||||
|
INLINE_KEYWORD to listOf(LanguageFeature.InlineProperties, LanguageFeature.InlineClasses),
|
||||||
|
HEADER_KEYWORD to listOf(LanguageFeature.MultiPlatformProjects),
|
||||||
|
IMPL_KEYWORD to listOf(LanguageFeature.MultiPlatformProjects),
|
||||||
|
EXPECT_KEYWORD to listOf(LanguageFeature.MultiPlatformProjects),
|
||||||
|
ACTUAL_KEYWORD to listOf(LanguageFeature.MultiPlatformProjects),
|
||||||
|
LATEINIT_KEYWORD to listOf(LanguageFeature.LateinitTopLevelProperties, LanguageFeature.LateinitLocalVariables),
|
||||||
|
FUN_KEYWORD to listOf(LanguageFeature.FunctionalInterfaceConversion)
|
||||||
|
)
|
||||||
|
|
||||||
|
val featureDependenciesTargets = mapOf(
|
||||||
|
LanguageFeature.InlineProperties to setOf(KotlinTarget.PROPERTY, KotlinTarget.PROPERTY_GETTER, KotlinTarget.PROPERTY_SETTER),
|
||||||
|
LanguageFeature.LateinitLocalVariables to setOf(KotlinTarget.LOCAL_VARIABLE),
|
||||||
|
LanguageFeature.LateinitTopLevelProperties to setOf(KotlinTarget.TOP_LEVEL_PROPERTY),
|
||||||
|
LanguageFeature.InlineClasses to setOf(KotlinTarget.CLASS_ONLY),
|
||||||
|
LanguageFeature.JvmInlineValueClasses to setOf(KotlinTarget.CLASS_ONLY),
|
||||||
|
LanguageFeature.FunctionalInterfaceConversion to setOf(KotlinTarget.INTERFACE)
|
||||||
|
)
|
||||||
|
|
||||||
|
val defaultVisibilityTargets: EnumSet<KotlinTarget> = EnumSet.of(
|
||||||
|
KotlinTarget.CLASS_ONLY, KotlinTarget.OBJECT, KotlinTarget.INTERFACE, KotlinTarget.ENUM_CLASS, KotlinTarget.ANNOTATION_CLASS,
|
||||||
|
KotlinTarget.MEMBER_FUNCTION, KotlinTarget.TOP_LEVEL_FUNCTION, KotlinTarget.PROPERTY_GETTER, KotlinTarget.PROPERTY_SETTER,
|
||||||
|
KotlinTarget.MEMBER_PROPERTY, KotlinTarget.TOP_LEVEL_PROPERTY, KotlinTarget.CONSTRUCTOR, KotlinTarget.TYPEALIAS
|
||||||
|
)
|
||||||
|
|
||||||
|
val possibleTargetMap = mapOf(
|
||||||
|
ENUM_KEYWORD to EnumSet.of(KotlinTarget.ENUM_CLASS),
|
||||||
|
ABSTRACT_KEYWORD to EnumSet.of(
|
||||||
|
KotlinTarget.CLASS_ONLY,
|
||||||
|
KotlinTarget.LOCAL_CLASS,
|
||||||
|
KotlinTarget.INTERFACE,
|
||||||
|
KotlinTarget.MEMBER_PROPERTY,
|
||||||
|
KotlinTarget.MEMBER_FUNCTION
|
||||||
|
),
|
||||||
|
OPEN_KEYWORD to EnumSet.of(
|
||||||
|
KotlinTarget.CLASS_ONLY,
|
||||||
|
KotlinTarget.LOCAL_CLASS,
|
||||||
|
KotlinTarget.INTERFACE,
|
||||||
|
KotlinTarget.MEMBER_PROPERTY,
|
||||||
|
KotlinTarget.MEMBER_FUNCTION
|
||||||
|
),
|
||||||
|
FINAL_KEYWORD to EnumSet.of(
|
||||||
|
KotlinTarget.CLASS_ONLY,
|
||||||
|
KotlinTarget.LOCAL_CLASS,
|
||||||
|
KotlinTarget.ENUM_CLASS,
|
||||||
|
KotlinTarget.OBJECT,
|
||||||
|
KotlinTarget.MEMBER_PROPERTY,
|
||||||
|
KotlinTarget.MEMBER_FUNCTION
|
||||||
|
),
|
||||||
|
SEALED_KEYWORD to EnumSet.of(KotlinTarget.CLASS_ONLY, KotlinTarget.INTERFACE),
|
||||||
|
INNER_KEYWORD to EnumSet.of(KotlinTarget.CLASS_ONLY),
|
||||||
|
OVERRIDE_KEYWORD to EnumSet.of(KotlinTarget.MEMBER_PROPERTY, KotlinTarget.MEMBER_FUNCTION),
|
||||||
|
PRIVATE_KEYWORD to defaultVisibilityTargets,
|
||||||
|
PUBLIC_KEYWORD to defaultVisibilityTargets,
|
||||||
|
INTERNAL_KEYWORD to defaultVisibilityTargets,
|
||||||
|
PROTECTED_KEYWORD to EnumSet.of(
|
||||||
|
KotlinTarget.CLASS_ONLY,
|
||||||
|
KotlinTarget.OBJECT,
|
||||||
|
KotlinTarget.INTERFACE,
|
||||||
|
KotlinTarget.ENUM_CLASS,
|
||||||
|
KotlinTarget.ANNOTATION_CLASS,
|
||||||
|
KotlinTarget.MEMBER_FUNCTION,
|
||||||
|
KotlinTarget.PROPERTY_GETTER,
|
||||||
|
KotlinTarget.PROPERTY_SETTER,
|
||||||
|
KotlinTarget.MEMBER_PROPERTY,
|
||||||
|
KotlinTarget.CONSTRUCTOR,
|
||||||
|
KotlinTarget.TYPEALIAS
|
||||||
|
),
|
||||||
|
IN_KEYWORD to EnumSet.of(KotlinTarget.TYPE_PARAMETER, KotlinTarget.TYPE_PROJECTION),
|
||||||
|
OUT_KEYWORD to EnumSet.of(KotlinTarget.TYPE_PARAMETER, KotlinTarget.TYPE_PROJECTION),
|
||||||
|
REIFIED_KEYWORD to EnumSet.of(KotlinTarget.TYPE_PARAMETER),
|
||||||
|
VARARG_KEYWORD to EnumSet.of(KotlinTarget.VALUE_PARAMETER, KotlinTarget.PROPERTY_PARAMETER),
|
||||||
|
COMPANION_KEYWORD to EnumSet.of(KotlinTarget.OBJECT),
|
||||||
|
LATEINIT_KEYWORD to EnumSet.of(KotlinTarget.MEMBER_PROPERTY, KotlinTarget.TOP_LEVEL_PROPERTY, KotlinTarget.LOCAL_VARIABLE),
|
||||||
|
DATA_KEYWORD to EnumSet.of(KotlinTarget.CLASS_ONLY, KotlinTarget.LOCAL_CLASS),
|
||||||
|
INLINE_KEYWORD to EnumSet.of(
|
||||||
|
KotlinTarget.FUNCTION,
|
||||||
|
KotlinTarget.PROPERTY,
|
||||||
|
KotlinTarget.PROPERTY_GETTER,
|
||||||
|
KotlinTarget.PROPERTY_SETTER,
|
||||||
|
KotlinTarget.CLASS_ONLY
|
||||||
|
),
|
||||||
|
NOINLINE_KEYWORD to EnumSet.of(KotlinTarget.VALUE_PARAMETER),
|
||||||
|
TAILREC_KEYWORD to EnumSet.of(KotlinTarget.FUNCTION),
|
||||||
|
SUSPEND_KEYWORD to EnumSet.of(KotlinTarget.MEMBER_FUNCTION, KotlinTarget.TOP_LEVEL_FUNCTION, KotlinTarget.LOCAL_FUNCTION),
|
||||||
|
EXTERNAL_KEYWORD to EnumSet.of(
|
||||||
|
KotlinTarget.FUNCTION,
|
||||||
|
KotlinTarget.PROPERTY,
|
||||||
|
KotlinTarget.PROPERTY_GETTER,
|
||||||
|
KotlinTarget.PROPERTY_SETTER,
|
||||||
|
KotlinTarget.CLASS
|
||||||
|
),
|
||||||
|
ANNOTATION_KEYWORD to EnumSet.of(KotlinTarget.ANNOTATION_CLASS),
|
||||||
|
CROSSINLINE_KEYWORD to EnumSet.of(KotlinTarget.VALUE_PARAMETER),
|
||||||
|
CONST_KEYWORD to EnumSet.of(KotlinTarget.MEMBER_PROPERTY, KotlinTarget.TOP_LEVEL_PROPERTY),
|
||||||
|
OPERATOR_KEYWORD to EnumSet.of(KotlinTarget.FUNCTION),
|
||||||
|
INFIX_KEYWORD to EnumSet.of(KotlinTarget.FUNCTION),
|
||||||
|
HEADER_KEYWORD to EnumSet.of(
|
||||||
|
KotlinTarget.TOP_LEVEL_FUNCTION,
|
||||||
|
KotlinTarget.TOP_LEVEL_PROPERTY,
|
||||||
|
KotlinTarget.CLASS_ONLY,
|
||||||
|
KotlinTarget.OBJECT,
|
||||||
|
KotlinTarget.INTERFACE,
|
||||||
|
KotlinTarget.ENUM_CLASS,
|
||||||
|
KotlinTarget.ANNOTATION_CLASS
|
||||||
|
),
|
||||||
|
IMPL_KEYWORD to EnumSet.of(
|
||||||
|
KotlinTarget.TOP_LEVEL_FUNCTION,
|
||||||
|
KotlinTarget.MEMBER_FUNCTION,
|
||||||
|
KotlinTarget.TOP_LEVEL_PROPERTY,
|
||||||
|
KotlinTarget.MEMBER_PROPERTY,
|
||||||
|
KotlinTarget.CONSTRUCTOR,
|
||||||
|
KotlinTarget.CLASS_ONLY,
|
||||||
|
KotlinTarget.OBJECT,
|
||||||
|
KotlinTarget.INTERFACE,
|
||||||
|
KotlinTarget.ENUM_CLASS,
|
||||||
|
KotlinTarget.ANNOTATION_CLASS,
|
||||||
|
KotlinTarget.TYPEALIAS
|
||||||
|
),
|
||||||
|
EXPECT_KEYWORD to EnumSet.of(
|
||||||
|
KotlinTarget.TOP_LEVEL_FUNCTION,
|
||||||
|
KotlinTarget.TOP_LEVEL_PROPERTY,
|
||||||
|
KotlinTarget.CLASS_ONLY,
|
||||||
|
KotlinTarget.OBJECT,
|
||||||
|
KotlinTarget.INTERFACE,
|
||||||
|
KotlinTarget.ENUM_CLASS,
|
||||||
|
KotlinTarget.ANNOTATION_CLASS
|
||||||
|
),
|
||||||
|
ACTUAL_KEYWORD to EnumSet.of(
|
||||||
|
KotlinTarget.TOP_LEVEL_FUNCTION,
|
||||||
|
KotlinTarget.MEMBER_FUNCTION,
|
||||||
|
KotlinTarget.TOP_LEVEL_PROPERTY,
|
||||||
|
KotlinTarget.MEMBER_PROPERTY,
|
||||||
|
KotlinTarget.CONSTRUCTOR,
|
||||||
|
KotlinTarget.CLASS_ONLY,
|
||||||
|
KotlinTarget.OBJECT,
|
||||||
|
KotlinTarget.INTERFACE,
|
||||||
|
KotlinTarget.ENUM_CLASS,
|
||||||
|
KotlinTarget.ANNOTATION_CLASS,
|
||||||
|
KotlinTarget.TYPEALIAS
|
||||||
|
),
|
||||||
|
FUN_KEYWORD to EnumSet.of(KotlinTarget.INTERFACE),
|
||||||
|
VALUE_KEYWORD to EnumSet.of(KotlinTarget.CLASS_ONLY)
|
||||||
|
)
|
||||||
|
|
||||||
|
// NOTE: deprecated targets must be possible!
|
||||||
|
val deprecatedTargetMap = mapOf<KtKeywordToken, Set<KotlinTarget>>()
|
||||||
|
|
||||||
|
val deprecatedParentTargetMap = mapOf<KtKeywordToken, Set<KotlinTarget>>()
|
||||||
|
|
||||||
|
val deprecatedModifierMap = mapOf(
|
||||||
|
HEADER_KEYWORD to EXPECT_KEYWORD,
|
||||||
|
IMPL_KEYWORD to ACTUAL_KEYWORD
|
||||||
|
)
|
||||||
|
|
||||||
|
// NOTE: redundant targets must be possible!
|
||||||
|
val redundantTargetMap = mapOf<KtKeywordToken, Set<KotlinTarget>>(
|
||||||
|
OPEN_KEYWORD to EnumSet.of(KotlinTarget.INTERFACE)
|
||||||
|
)
|
||||||
|
|
||||||
|
interface TargetAllowedPredicate {
|
||||||
|
fun isAllowed(target: KotlinTarget, languageVersionSettings: LanguageVersionSettings): Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
fun always(target: KotlinTarget, vararg targets: KotlinTarget) = object : TargetAllowedPredicate {
|
||||||
|
private val targetSet = EnumSet.of(target, *targets)
|
||||||
|
|
||||||
|
override fun isAllowed(target: KotlinTarget, languageVersionSettings: LanguageVersionSettings) =
|
||||||
|
target in targetSet
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ifSupported(languageFeature: LanguageFeature, target: KotlinTarget, vararg targets: KotlinTarget) =
|
||||||
|
object : TargetAllowedPredicate {
|
||||||
|
private val targetSet = EnumSet.of(target, *targets)
|
||||||
|
|
||||||
|
override fun isAllowed(target: KotlinTarget, languageVersionSettings: LanguageVersionSettings) =
|
||||||
|
languageVersionSettings.supportsFeature(languageFeature) && target in targetSet
|
||||||
|
}
|
||||||
|
|
||||||
|
fun or(p1: TargetAllowedPredicate, p2: TargetAllowedPredicate) = object : TargetAllowedPredicate {
|
||||||
|
override fun isAllowed(target: KotlinTarget, languageVersionSettings: LanguageVersionSettings) =
|
||||||
|
p1.isAllowed(target, languageVersionSettings) ||
|
||||||
|
p2.isAllowed(target, languageVersionSettings)
|
||||||
|
}
|
||||||
|
|
||||||
|
val possibleParentTargetPredicateMap = mapOf(
|
||||||
|
INNER_KEYWORD to or(
|
||||||
|
always(KotlinTarget.CLASS_ONLY, KotlinTarget.LOCAL_CLASS, KotlinTarget.ENUM_CLASS),
|
||||||
|
ifSupported(LanguageFeature.InnerClassInEnumEntryClass, KotlinTarget.ENUM_ENTRY)
|
||||||
|
),
|
||||||
|
OVERRIDE_KEYWORD to always(
|
||||||
|
KotlinTarget.CLASS_ONLY,
|
||||||
|
KotlinTarget.LOCAL_CLASS,
|
||||||
|
KotlinTarget.OBJECT,
|
||||||
|
KotlinTarget.OBJECT_LITERAL,
|
||||||
|
KotlinTarget.INTERFACE,
|
||||||
|
KotlinTarget.ENUM_CLASS,
|
||||||
|
KotlinTarget.ENUM_ENTRY
|
||||||
|
),
|
||||||
|
PROTECTED_KEYWORD to always(KotlinTarget.CLASS_ONLY, KotlinTarget.LOCAL_CLASS, KotlinTarget.ENUM_CLASS, KotlinTarget.COMPANION_OBJECT),
|
||||||
|
INTERNAL_KEYWORD to always(
|
||||||
|
KotlinTarget.CLASS_ONLY,
|
||||||
|
KotlinTarget.LOCAL_CLASS,
|
||||||
|
KotlinTarget.OBJECT,
|
||||||
|
KotlinTarget.OBJECT_LITERAL,
|
||||||
|
KotlinTarget.ENUM_CLASS,
|
||||||
|
KotlinTarget.ENUM_ENTRY,
|
||||||
|
KotlinTarget.FILE
|
||||||
|
),
|
||||||
|
PRIVATE_KEYWORD to always(
|
||||||
|
KotlinTarget.CLASS_ONLY,
|
||||||
|
KotlinTarget.LOCAL_CLASS,
|
||||||
|
KotlinTarget.OBJECT,
|
||||||
|
KotlinTarget.OBJECT_LITERAL,
|
||||||
|
KotlinTarget.INTERFACE,
|
||||||
|
KotlinTarget.ENUM_CLASS,
|
||||||
|
KotlinTarget.ENUM_ENTRY,
|
||||||
|
KotlinTarget.FILE
|
||||||
|
),
|
||||||
|
COMPANION_KEYWORD to always(
|
||||||
|
KotlinTarget.CLASS_ONLY,
|
||||||
|
KotlinTarget.INTERFACE,
|
||||||
|
KotlinTarget.ENUM_CLASS,
|
||||||
|
KotlinTarget.ANNOTATION_CLASS
|
||||||
|
),
|
||||||
|
FINAL_KEYWORD to always(
|
||||||
|
KotlinTarget.CLASS_ONLY,
|
||||||
|
KotlinTarget.LOCAL_CLASS,
|
||||||
|
KotlinTarget.OBJECT,
|
||||||
|
KotlinTarget.OBJECT_LITERAL,
|
||||||
|
KotlinTarget.ENUM_CLASS,
|
||||||
|
KotlinTarget.ENUM_ENTRY,
|
||||||
|
KotlinTarget.ANNOTATION_CLASS,
|
||||||
|
KotlinTarget.FILE
|
||||||
|
),
|
||||||
|
VARARG_KEYWORD to always(KotlinTarget.CONSTRUCTOR, KotlinTarget.FUNCTION, KotlinTarget.CLASS)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
-400
@@ -1,400 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.resolve;
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.*
|
|
||||||
import java.util.*
|
|
||||||
import org.jetbrains.kotlin.resolve.KeywordType.*
|
|
||||||
|
|
||||||
enum class KeywordType {
|
|
||||||
Inner,
|
|
||||||
Override,
|
|
||||||
Public,
|
|
||||||
Protected,
|
|
||||||
Internal,
|
|
||||||
Private,
|
|
||||||
Companion,
|
|
||||||
Final,
|
|
||||||
Vararg,
|
|
||||||
Enum,
|
|
||||||
Abstract,
|
|
||||||
Open,
|
|
||||||
Sealed,
|
|
||||||
In,
|
|
||||||
Out,
|
|
||||||
Reified,
|
|
||||||
Lateinit,
|
|
||||||
Data,
|
|
||||||
Inline,
|
|
||||||
Noinline,
|
|
||||||
Tailrec,
|
|
||||||
Suspend,
|
|
||||||
External,
|
|
||||||
Annotation,
|
|
||||||
Crossinline,
|
|
||||||
Const,
|
|
||||||
Operator,
|
|
||||||
Infix,
|
|
||||||
Header,
|
|
||||||
Impl,
|
|
||||||
Expect,
|
|
||||||
Actual,
|
|
||||||
Fun,
|
|
||||||
Value
|
|
||||||
}
|
|
||||||
|
|
||||||
fun KeywordType.render(): String {
|
|
||||||
return toString().lowercase()
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class Compatibility {
|
|
||||||
// modifier pair is compatible: ok (default)
|
|
||||||
COMPATIBLE,
|
|
||||||
|
|
||||||
// second is redundant to first: warning
|
|
||||||
REDUNDANT,
|
|
||||||
|
|
||||||
// first is redundant to second: warning
|
|
||||||
REVERSE_REDUNDANT,
|
|
||||||
|
|
||||||
// error
|
|
||||||
REPEATED,
|
|
||||||
|
|
||||||
// pair is deprecated, will become incompatible: warning
|
|
||||||
DEPRECATED,
|
|
||||||
|
|
||||||
// pair is incompatible: error
|
|
||||||
INCOMPATIBLE,
|
|
||||||
|
|
||||||
// same but only for functions / properties: error
|
|
||||||
COMPATIBLE_FOR_CLASSES_ONLY
|
|
||||||
}
|
|
||||||
|
|
||||||
val compatibilityTypeMap = hashMapOf<Pair<KeywordType, KeywordType>, Compatibility>()
|
|
||||||
|
|
||||||
fun compatibility(first: KeywordType, second: KeywordType): Compatibility {
|
|
||||||
return if (first == second) {
|
|
||||||
Compatibility.REPEATED
|
|
||||||
} else {
|
|
||||||
mutualCompatibility[Pair(first, second)] ?: Compatibility.COMPATIBLE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// First modifier in pair should be also first in declaration
|
|
||||||
private val mutualCompatibility = buildCompatibilityMap()
|
|
||||||
|
|
||||||
private fun buildCompatibilityMap(): Map<Pair<KeywordType, KeywordType>, Compatibility> {
|
|
||||||
val result = hashMapOf<Pair<KeywordType, KeywordType>, Compatibility>()
|
|
||||||
// Variance: in + out are incompatible
|
|
||||||
result += incompatibilityRegister(In, Out)
|
|
||||||
// Visibilities: incompatible
|
|
||||||
result += incompatibilityRegister(Private, Protected, Public, Internal)
|
|
||||||
// Abstract + open + final + sealed: incompatible
|
|
||||||
result += incompatibilityRegister(Abstract, Open, Final, Sealed)
|
|
||||||
// data + open, data + inner, data + abstract, data + sealed, data + inline, data + value
|
|
||||||
result += incompatibilityRegister(Data, Open)
|
|
||||||
result += incompatibilityRegister(Data, Inner)
|
|
||||||
result += incompatibilityRegister(Data, Abstract)
|
|
||||||
result += incompatibilityRegister(Data, Sealed)
|
|
||||||
result += incompatibilityRegister(Data, Inline)
|
|
||||||
result += incompatibilityRegister(Data, Value)
|
|
||||||
// open is redundant to abstract & override
|
|
||||||
result += redundantRegister(Abstract, Open)
|
|
||||||
// abstract is redundant to sealed
|
|
||||||
result += redundantRegister(Sealed, Abstract)
|
|
||||||
|
|
||||||
// const is incompatible with abstract, open, override
|
|
||||||
result += incompatibilityRegister(Const, Abstract)
|
|
||||||
result += incompatibilityRegister(Const, Open)
|
|
||||||
result += incompatibilityRegister(Const, Override)
|
|
||||||
|
|
||||||
// private is incompatible with override
|
|
||||||
result += incompatibilityRegister(Private, Override)
|
|
||||||
// private is compatible with open / abstract only for classes
|
|
||||||
result += compatibilityForClassesRegister(Private, Open)
|
|
||||||
result += compatibilityForClassesRegister(Private, Abstract)
|
|
||||||
|
|
||||||
result += incompatibilityRegister(Crossinline, Noinline)
|
|
||||||
|
|
||||||
// 1. subclasses contained inside a sealed class can not be instantiated, because their constructors needs
|
|
||||||
// an instance of an outer sealed (effectively abstract) class
|
|
||||||
// 2. subclasses of a non-top-level sealed class must be declared inside the class
|
|
||||||
// (see the KEEP https://github.com/Kotlin/KEEP/blob/master/proposals/sealed-class-inheritance.md)
|
|
||||||
result += incompatibilityRegister(Sealed, Inner)
|
|
||||||
|
|
||||||
// header / expect / impl / actual are all incompatible
|
|
||||||
result += incompatibilityRegister(Header, Expect, Impl, Actual)
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun incompatibilityRegister(vararg list: KeywordType): Map<Pair<KeywordType, KeywordType>, Compatibility> {
|
|
||||||
return compatibilityRegister(Compatibility.INCOMPATIBLE, *list)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun redundantRegister(
|
|
||||||
sufficient: KeywordType,
|
|
||||||
redundant: KeywordType
|
|
||||||
): Map<Pair<KeywordType, KeywordType>, Compatibility> {
|
|
||||||
return mapOf(
|
|
||||||
Pair(sufficient, redundant) to Compatibility.REDUNDANT,
|
|
||||||
Pair(redundant, sufficient) to Compatibility.REVERSE_REDUNDANT
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun compatibilityForClassesRegister(vararg list: KeywordType) =
|
|
||||||
compatibilityRegister(Compatibility.COMPATIBLE_FOR_CLASSES_ONLY, *list)
|
|
||||||
|
|
||||||
private fun compatibilityRegister(
|
|
||||||
compatibility: Compatibility, vararg list: KeywordType
|
|
||||||
): Map<Pair<KeywordType, KeywordType>, Compatibility> {
|
|
||||||
val result = hashMapOf<Pair<KeywordType, KeywordType>, Compatibility>()
|
|
||||||
for (first in list) {
|
|
||||||
for (second in list) {
|
|
||||||
if (first != second) {
|
|
||||||
result[Pair(first, second)] = compatibility
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
val featureDependencies = mapOf(
|
|
||||||
Suspend to listOf(LanguageFeature.Coroutines),
|
|
||||||
Inline to listOf(LanguageFeature.InlineProperties, LanguageFeature.InlineClasses),
|
|
||||||
Header to listOf(LanguageFeature.MultiPlatformProjects),
|
|
||||||
Impl to listOf(LanguageFeature.MultiPlatformProjects),
|
|
||||||
Expect to listOf(LanguageFeature.MultiPlatformProjects),
|
|
||||||
Actual to listOf(LanguageFeature.MultiPlatformProjects),
|
|
||||||
Lateinit to listOf(LanguageFeature.LateinitTopLevelProperties, LanguageFeature.LateinitLocalVariables),
|
|
||||||
Fun to listOf(LanguageFeature.FunctionalInterfaceConversion)
|
|
||||||
)
|
|
||||||
|
|
||||||
val featureDependenciesTargets = mapOf(
|
|
||||||
LanguageFeature.InlineProperties to setOf(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER),
|
|
||||||
LanguageFeature.LateinitLocalVariables to setOf(LOCAL_VARIABLE),
|
|
||||||
LanguageFeature.LateinitTopLevelProperties to setOf(TOP_LEVEL_PROPERTY),
|
|
||||||
LanguageFeature.InlineClasses to setOf(CLASS_ONLY),
|
|
||||||
LanguageFeature.JvmInlineValueClasses to setOf(CLASS_ONLY),
|
|
||||||
LanguageFeature.FunctionalInterfaceConversion to setOf(INTERFACE)
|
|
||||||
)
|
|
||||||
|
|
||||||
val defaultVisibilityTargets: EnumSet<KotlinTarget> = EnumSet.of(
|
|
||||||
CLASS_ONLY, OBJECT, INTERFACE, ENUM_CLASS, ANNOTATION_CLASS,
|
|
||||||
MEMBER_FUNCTION, TOP_LEVEL_FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER,
|
|
||||||
MEMBER_PROPERTY, TOP_LEVEL_PROPERTY, CONSTRUCTOR, TYPEALIAS
|
|
||||||
)
|
|
||||||
|
|
||||||
val possibleTargetMap = mapOf(
|
|
||||||
KeywordType.Enum to EnumSet.of(ENUM_CLASS),
|
|
||||||
Abstract to EnumSet.of(
|
|
||||||
CLASS_ONLY,
|
|
||||||
LOCAL_CLASS,
|
|
||||||
INTERFACE,
|
|
||||||
MEMBER_PROPERTY,
|
|
||||||
MEMBER_FUNCTION
|
|
||||||
),
|
|
||||||
Open to EnumSet.of(
|
|
||||||
CLASS_ONLY,
|
|
||||||
LOCAL_CLASS,
|
|
||||||
INTERFACE,
|
|
||||||
MEMBER_PROPERTY,
|
|
||||||
MEMBER_FUNCTION
|
|
||||||
),
|
|
||||||
Final to EnumSet.of(
|
|
||||||
CLASS_ONLY,
|
|
||||||
LOCAL_CLASS,
|
|
||||||
ENUM_CLASS,
|
|
||||||
OBJECT,
|
|
||||||
MEMBER_PROPERTY,
|
|
||||||
MEMBER_FUNCTION
|
|
||||||
),
|
|
||||||
Sealed to EnumSet.of(CLASS_ONLY, INTERFACE),
|
|
||||||
Inner to EnumSet.of(CLASS_ONLY),
|
|
||||||
Override to EnumSet.of(MEMBER_PROPERTY, MEMBER_FUNCTION),
|
|
||||||
Private to defaultVisibilityTargets,
|
|
||||||
Public to defaultVisibilityTargets,
|
|
||||||
Internal to defaultVisibilityTargets,
|
|
||||||
Protected to EnumSet.of(
|
|
||||||
CLASS_ONLY,
|
|
||||||
OBJECT,
|
|
||||||
INTERFACE,
|
|
||||||
ENUM_CLASS,
|
|
||||||
ANNOTATION_CLASS,
|
|
||||||
MEMBER_FUNCTION,
|
|
||||||
PROPERTY_GETTER,
|
|
||||||
PROPERTY_SETTER,
|
|
||||||
MEMBER_PROPERTY,
|
|
||||||
CONSTRUCTOR,
|
|
||||||
TYPEALIAS
|
|
||||||
),
|
|
||||||
In to EnumSet.of(TYPE_PARAMETER, TYPE_PROJECTION),
|
|
||||||
Out to EnumSet.of(TYPE_PARAMETER, TYPE_PROJECTION),
|
|
||||||
Reified to EnumSet.of(TYPE_PARAMETER),
|
|
||||||
Vararg to EnumSet.of(VALUE_PARAMETER, PROPERTY_PARAMETER),
|
|
||||||
KeywordType.Companion to EnumSet.of(OBJECT),
|
|
||||||
Lateinit to EnumSet.of(MEMBER_PROPERTY, TOP_LEVEL_PROPERTY, LOCAL_VARIABLE),
|
|
||||||
Data to EnumSet.of(CLASS_ONLY, LOCAL_CLASS),
|
|
||||||
Inline to EnumSet.of(
|
|
||||||
FUNCTION,
|
|
||||||
PROPERTY,
|
|
||||||
PROPERTY_GETTER,
|
|
||||||
PROPERTY_SETTER,
|
|
||||||
CLASS_ONLY
|
|
||||||
),
|
|
||||||
Noinline to EnumSet.of(VALUE_PARAMETER),
|
|
||||||
Tailrec to EnumSet.of(FUNCTION),
|
|
||||||
Suspend to EnumSet.of(MEMBER_FUNCTION, TOP_LEVEL_FUNCTION, LOCAL_FUNCTION),
|
|
||||||
External to EnumSet.of(
|
|
||||||
FUNCTION,
|
|
||||||
PROPERTY,
|
|
||||||
PROPERTY_GETTER,
|
|
||||||
PROPERTY_SETTER,
|
|
||||||
CLASS
|
|
||||||
),
|
|
||||||
KeywordType.Annotation to EnumSet.of(ANNOTATION_CLASS), // TODO: Workaround for FIR, https://youtrack.jetbrains.com/issue/KT-48157
|
|
||||||
Crossinline to EnumSet.of(VALUE_PARAMETER),
|
|
||||||
Const to EnumSet.of(MEMBER_PROPERTY, TOP_LEVEL_PROPERTY),
|
|
||||||
Operator to EnumSet.of(FUNCTION),
|
|
||||||
Infix to EnumSet.of(FUNCTION),
|
|
||||||
Header to EnumSet.of(
|
|
||||||
TOP_LEVEL_FUNCTION,
|
|
||||||
TOP_LEVEL_PROPERTY,
|
|
||||||
CLASS_ONLY,
|
|
||||||
OBJECT,
|
|
||||||
INTERFACE,
|
|
||||||
ENUM_CLASS,
|
|
||||||
ANNOTATION_CLASS
|
|
||||||
),
|
|
||||||
Impl to EnumSet.of(
|
|
||||||
TOP_LEVEL_FUNCTION,
|
|
||||||
MEMBER_FUNCTION,
|
|
||||||
TOP_LEVEL_PROPERTY,
|
|
||||||
MEMBER_PROPERTY,
|
|
||||||
CONSTRUCTOR,
|
|
||||||
CLASS_ONLY,
|
|
||||||
OBJECT,
|
|
||||||
INTERFACE,
|
|
||||||
ENUM_CLASS,
|
|
||||||
ANNOTATION_CLASS,
|
|
||||||
TYPEALIAS
|
|
||||||
),
|
|
||||||
Expect to EnumSet.of(
|
|
||||||
TOP_LEVEL_FUNCTION,
|
|
||||||
TOP_LEVEL_PROPERTY,
|
|
||||||
CLASS_ONLY,
|
|
||||||
OBJECT,
|
|
||||||
INTERFACE,
|
|
||||||
ENUM_CLASS,
|
|
||||||
ANNOTATION_CLASS
|
|
||||||
),
|
|
||||||
Actual to EnumSet.of(
|
|
||||||
TOP_LEVEL_FUNCTION,
|
|
||||||
MEMBER_FUNCTION,
|
|
||||||
TOP_LEVEL_PROPERTY,
|
|
||||||
MEMBER_PROPERTY,
|
|
||||||
CONSTRUCTOR,
|
|
||||||
CLASS_ONLY,
|
|
||||||
OBJECT,
|
|
||||||
INTERFACE,
|
|
||||||
ENUM_CLASS,
|
|
||||||
ANNOTATION_CLASS,
|
|
||||||
TYPEALIAS
|
|
||||||
),
|
|
||||||
Fun to EnumSet.of(INTERFACE),
|
|
||||||
Value to EnumSet.of(CLASS_ONLY)
|
|
||||||
)
|
|
||||||
|
|
||||||
// NOTE: deprecated targets must be possible!
|
|
||||||
val deprecatedTargetMap = mapOf<KeywordType, Set<KotlinTarget>>()
|
|
||||||
|
|
||||||
val deprecatedParentTargetMap = mapOf<KeywordType, Set<KotlinTarget>>()
|
|
||||||
|
|
||||||
val deprecatedModifierMap = mapOf(
|
|
||||||
Header to Expect,
|
|
||||||
Impl to Actual
|
|
||||||
)
|
|
||||||
|
|
||||||
// NOTE: redundant targets must be possible!
|
|
||||||
val redundantTargetMap = mapOf<KeywordType, Set<KotlinTarget>>(
|
|
||||||
Open to EnumSet.of(INTERFACE)
|
|
||||||
)
|
|
||||||
|
|
||||||
interface TargetAllowedPredicate {
|
|
||||||
fun isAllowed(target: KotlinTarget, languageVersionSettings: LanguageVersionSettings): Boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
fun always(target: KotlinTarget, vararg targets: KotlinTarget) = object : TargetAllowedPredicate {
|
|
||||||
private val targetSet = EnumSet.of(target, *targets)
|
|
||||||
|
|
||||||
override fun isAllowed(target: KotlinTarget, languageVersionSettings: LanguageVersionSettings) =
|
|
||||||
target in targetSet
|
|
||||||
}
|
|
||||||
|
|
||||||
fun ifSupported(languageFeature: LanguageFeature, target: KotlinTarget, vararg targets: KotlinTarget) =
|
|
||||||
object : TargetAllowedPredicate {
|
|
||||||
private val targetSet = EnumSet.of(target, *targets)
|
|
||||||
|
|
||||||
override fun isAllowed(target: KotlinTarget, languageVersionSettings: LanguageVersionSettings) =
|
|
||||||
languageVersionSettings.supportsFeature(languageFeature) && target in targetSet
|
|
||||||
}
|
|
||||||
|
|
||||||
fun or(p1: TargetAllowedPredicate, p2: TargetAllowedPredicate) = object : TargetAllowedPredicate {
|
|
||||||
override fun isAllowed(target: KotlinTarget, languageVersionSettings: LanguageVersionSettings) =
|
|
||||||
p1.isAllowed(target, languageVersionSettings) ||
|
|
||||||
p2.isAllowed(target, languageVersionSettings)
|
|
||||||
}
|
|
||||||
|
|
||||||
val possibleParentTargetPredicateMap = mapOf(
|
|
||||||
Inner to or(
|
|
||||||
always(CLASS_ONLY, LOCAL_CLASS, ENUM_CLASS),
|
|
||||||
ifSupported(LanguageFeature.InnerClassInEnumEntryClass, ENUM_ENTRY)
|
|
||||||
),
|
|
||||||
Override to always(
|
|
||||||
CLASS_ONLY,
|
|
||||||
LOCAL_CLASS,
|
|
||||||
OBJECT,
|
|
||||||
OBJECT_LITERAL,
|
|
||||||
INTERFACE,
|
|
||||||
ENUM_CLASS,
|
|
||||||
ENUM_ENTRY
|
|
||||||
),
|
|
||||||
Protected to always(CLASS_ONLY, LOCAL_CLASS, ENUM_CLASS, COMPANION_OBJECT),
|
|
||||||
Internal to always(
|
|
||||||
CLASS_ONLY,
|
|
||||||
LOCAL_CLASS,
|
|
||||||
OBJECT,
|
|
||||||
OBJECT_LITERAL,
|
|
||||||
ENUM_CLASS,
|
|
||||||
ENUM_ENTRY,
|
|
||||||
FILE
|
|
||||||
),
|
|
||||||
Private to always(
|
|
||||||
CLASS_ONLY,
|
|
||||||
LOCAL_CLASS,
|
|
||||||
OBJECT,
|
|
||||||
OBJECT_LITERAL,
|
|
||||||
INTERFACE,
|
|
||||||
ENUM_CLASS,
|
|
||||||
ENUM_ENTRY,
|
|
||||||
FILE
|
|
||||||
),
|
|
||||||
KeywordType.Companion to always(CLASS_ONLY, INTERFACE, ENUM_CLASS, ANNOTATION_CLASS),
|
|
||||||
Final to always(
|
|
||||||
CLASS_ONLY,
|
|
||||||
LOCAL_CLASS,
|
|
||||||
OBJECT,
|
|
||||||
OBJECT_LITERAL,
|
|
||||||
ENUM_CLASS,
|
|
||||||
ENUM_ENTRY,
|
|
||||||
ANNOTATION_CLASS,
|
|
||||||
FILE
|
|
||||||
),
|
|
||||||
Vararg to always(CONSTRUCTOR, FUNCTION, CLASS)
|
|
||||||
)
|
|
||||||
+15
-14
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableLikeSymbol
|
|||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableSymbol
|
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.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
@@ -723,43 +724,43 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
|
|
||||||
abstract class RepeatedModifier : KtFirDiagnostic<PsiElement>() {
|
abstract class RepeatedModifier : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = RepeatedModifier::class
|
override val diagnosticClass get() = RepeatedModifier::class
|
||||||
abstract val modifier: String
|
abstract val modifier: KtModifierKeywordToken
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class RedundantModifier : KtFirDiagnostic<PsiElement>() {
|
abstract class RedundantModifier : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = RedundantModifier::class
|
override val diagnosticClass get() = RedundantModifier::class
|
||||||
abstract val redundantModifier: String
|
abstract val redundantModifier: KtModifierKeywordToken
|
||||||
abstract val conflictingModifier: String
|
abstract val conflictingModifier: KtModifierKeywordToken
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class DeprecatedModifier : KtFirDiagnostic<PsiElement>() {
|
abstract class DeprecatedModifier : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = DeprecatedModifier::class
|
override val diagnosticClass get() = DeprecatedModifier::class
|
||||||
abstract val deprecatedModifier: String
|
abstract val deprecatedModifier: KtModifierKeywordToken
|
||||||
abstract val actualModifier: String
|
abstract val actualModifier: KtModifierKeywordToken
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class DeprecatedModifierPair : KtFirDiagnostic<PsiElement>() {
|
abstract class DeprecatedModifierPair : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = DeprecatedModifierPair::class
|
override val diagnosticClass get() = DeprecatedModifierPair::class
|
||||||
abstract val deprecatedModifier: String
|
abstract val deprecatedModifier: KtModifierKeywordToken
|
||||||
abstract val conflictingModifier: String
|
abstract val conflictingModifier: KtModifierKeywordToken
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class DeprecatedModifierForTarget : KtFirDiagnostic<PsiElement>() {
|
abstract class DeprecatedModifierForTarget : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = DeprecatedModifierForTarget::class
|
override val diagnosticClass get() = DeprecatedModifierForTarget::class
|
||||||
abstract val deprecatedModifier: String
|
abstract val deprecatedModifier: KtModifierKeywordToken
|
||||||
abstract val target: String
|
abstract val target: String
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class RedundantModifierForTarget : KtFirDiagnostic<PsiElement>() {
|
abstract class RedundantModifierForTarget : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = RedundantModifierForTarget::class
|
override val diagnosticClass get() = RedundantModifierForTarget::class
|
||||||
abstract val redundantModifier: String
|
abstract val redundantModifier: KtModifierKeywordToken
|
||||||
abstract val target: String
|
abstract val target: String
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class IncompatibleModifiers : KtFirDiagnostic<PsiElement>() {
|
abstract class IncompatibleModifiers : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = IncompatibleModifiers::class
|
override val diagnosticClass get() = IncompatibleModifiers::class
|
||||||
abstract val modifier1: String
|
abstract val modifier1: KtModifierKeywordToken
|
||||||
abstract val modifier2: String
|
abstract val modifier2: KtModifierKeywordToken
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class RedundantOpenInInterface : KtFirDiagnostic<KtModifierListOwner>() {
|
abstract class RedundantOpenInInterface : KtFirDiagnostic<KtModifierListOwner>() {
|
||||||
@@ -768,7 +769,7 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
|
|
||||||
abstract class WrongModifierTarget : KtFirDiagnostic<PsiElement>() {
|
abstract class WrongModifierTarget : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = WrongModifierTarget::class
|
override val diagnosticClass get() = WrongModifierTarget::class
|
||||||
abstract val modifier: String
|
abstract val modifier: KtModifierKeywordToken
|
||||||
abstract val target: String
|
abstract val target: String
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -785,13 +786,13 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
|
|
||||||
abstract class WrongModifierContainingDeclaration : KtFirDiagnostic<PsiElement>() {
|
abstract class WrongModifierContainingDeclaration : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = WrongModifierContainingDeclaration::class
|
override val diagnosticClass get() = WrongModifierContainingDeclaration::class
|
||||||
abstract val modifier: String
|
abstract val modifier: KtModifierKeywordToken
|
||||||
abstract val target: String
|
abstract val target: String
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class DeprecatedModifierContainingDeclaration : KtFirDiagnostic<PsiElement>() {
|
abstract class DeprecatedModifierContainingDeclaration : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = DeprecatedModifierContainingDeclaration::class
|
override val diagnosticClass get() = DeprecatedModifierContainingDeclaration::class
|
||||||
abstract val modifier: String
|
abstract val modifier: KtModifierKeywordToken
|
||||||
abstract val target: String
|
abstract val target: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
-14
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableSymbol
|
|||||||
import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken
|
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.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
@@ -1149,7 +1150,7 @@ internal class InapplicableInfixModifierImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class RepeatedModifierImpl(
|
internal class RepeatedModifierImpl(
|
||||||
override val modifier: String,
|
override val modifier: KtModifierKeywordToken,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtFirDiagnostic.RepeatedModifier(), KtAbstractFirDiagnostic<PsiElement> {
|
) : KtFirDiagnostic.RepeatedModifier(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
@@ -1157,8 +1158,8 @@ internal class RepeatedModifierImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class RedundantModifierImpl(
|
internal class RedundantModifierImpl(
|
||||||
override val redundantModifier: String,
|
override val redundantModifier: KtModifierKeywordToken,
|
||||||
override val conflictingModifier: String,
|
override val conflictingModifier: KtModifierKeywordToken,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtFirDiagnostic.RedundantModifier(), KtAbstractFirDiagnostic<PsiElement> {
|
) : KtFirDiagnostic.RedundantModifier(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
@@ -1166,8 +1167,8 @@ internal class RedundantModifierImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class DeprecatedModifierImpl(
|
internal class DeprecatedModifierImpl(
|
||||||
override val deprecatedModifier: String,
|
override val deprecatedModifier: KtModifierKeywordToken,
|
||||||
override val actualModifier: String,
|
override val actualModifier: KtModifierKeywordToken,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtFirDiagnostic.DeprecatedModifier(), KtAbstractFirDiagnostic<PsiElement> {
|
) : KtFirDiagnostic.DeprecatedModifier(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
@@ -1175,8 +1176,8 @@ internal class DeprecatedModifierImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class DeprecatedModifierPairImpl(
|
internal class DeprecatedModifierPairImpl(
|
||||||
override val deprecatedModifier: String,
|
override val deprecatedModifier: KtModifierKeywordToken,
|
||||||
override val conflictingModifier: String,
|
override val conflictingModifier: KtModifierKeywordToken,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtFirDiagnostic.DeprecatedModifierPair(), KtAbstractFirDiagnostic<PsiElement> {
|
) : KtFirDiagnostic.DeprecatedModifierPair(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
@@ -1184,7 +1185,7 @@ internal class DeprecatedModifierPairImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class DeprecatedModifierForTargetImpl(
|
internal class DeprecatedModifierForTargetImpl(
|
||||||
override val deprecatedModifier: String,
|
override val deprecatedModifier: KtModifierKeywordToken,
|
||||||
override val target: String,
|
override val target: String,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
@@ -1193,7 +1194,7 @@ internal class DeprecatedModifierForTargetImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class RedundantModifierForTargetImpl(
|
internal class RedundantModifierForTargetImpl(
|
||||||
override val redundantModifier: String,
|
override val redundantModifier: KtModifierKeywordToken,
|
||||||
override val target: String,
|
override val target: String,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
@@ -1202,8 +1203,8 @@ internal class RedundantModifierForTargetImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class IncompatibleModifiersImpl(
|
internal class IncompatibleModifiersImpl(
|
||||||
override val modifier1: String,
|
override val modifier1: KtModifierKeywordToken,
|
||||||
override val modifier2: String,
|
override val modifier2: KtModifierKeywordToken,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
) : KtFirDiagnostic.IncompatibleModifiers(), KtAbstractFirDiagnostic<PsiElement> {
|
) : KtFirDiagnostic.IncompatibleModifiers(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
@@ -1218,7 +1219,7 @@ internal class RedundantOpenInInterfaceImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class WrongModifierTargetImpl(
|
internal class WrongModifierTargetImpl(
|
||||||
override val modifier: String,
|
override val modifier: KtModifierKeywordToken,
|
||||||
override val target: String,
|
override val target: String,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
@@ -1244,7 +1245,7 @@ internal class InfixModifierRequiredImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class WrongModifierContainingDeclarationImpl(
|
internal class WrongModifierContainingDeclarationImpl(
|
||||||
override val modifier: String,
|
override val modifier: KtModifierKeywordToken,
|
||||||
override val target: String,
|
override val target: String,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
@@ -1253,7 +1254,7 @@ internal class WrongModifierContainingDeclarationImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class DeprecatedModifierContainingDeclarationImpl(
|
internal class DeprecatedModifierContainingDeclarationImpl(
|
||||||
override val modifier: String,
|
override val modifier: KtModifierKeywordToken,
|
||||||
override val target: String,
|
override val target: String,
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
|
|||||||
Reference in New Issue
Block a user