[FIR] Implement WRONG_MODIFIER_CONTAINING_DECLARATION, DEPRECATED_MODIFIER_CONTAINING_DECLARATION

This commit is contained in:
Ivan Kochurkin
2021-08-04 22:24:51 +03:00
committed by TeamCityServer
parent cd6384eb20
commit 2c1c24c042
52 changed files with 167 additions and 223 deletions
@@ -1,5 +1,5 @@
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>public<!> class B <!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>public<!> class B
<!INCOMPATIBLE_MODIFIERS!>protected<!> <!INCOMPATIBLE_MODIFIERS!>internal<!> class C <!WRONG_MODIFIER_CONTAINING_DECLARATION!>protected<!> <!INCOMPATIBLE_MODIFIERS!>internal<!> class C
<!INCOMPATIBLE_MODIFIERS!>final<!> <!INCOMPATIBLE_MODIFIERS!>abstract<!> class D <!INCOMPATIBLE_MODIFIERS!>final<!> <!INCOMPATIBLE_MODIFIERS!>abstract<!> class D
<!INCOMPATIBLE_MODIFIERS!>final<!> <!INCOMPATIBLE_MODIFIERS!>open<!> class E <!INCOMPATIBLE_MODIFIERS!>final<!> <!INCOMPATIBLE_MODIFIERS!>open<!> class E
@@ -10,7 +10,7 @@ interface Interface {
// Redundant // Redundant
<!REDUNDANT_MODALITY_MODIFIER!>abstract<!> fun foo() <!REDUNDANT_MODALITY_MODIFIER!>abstract<!> fun foo()
// error // error
<!PRIVATE_FUNCTION_WITH_NO_BODY!>private<!> final fun bar() <!PRIVATE_FUNCTION_WITH_NO_BODY!>private<!> <!WRONG_MODIFIER_CONTAINING_DECLARATION!>final<!> fun bar()
<!REDUNDANT_MODALITY_MODIFIER!>open<!> fun goo() {} <!REDUNDANT_MODALITY_MODIFIER!>open<!> fun goo() {}
<!REDUNDANT_MODALITY_MODIFIER!>abstract<!> fun tar() <!REDUNDANT_MODALITY_MODIFIER!>abstract<!> fun tar()
@@ -63,7 +63,7 @@ interface Derived : Interface {
// Redundant // Redundant
override <!REDUNDANT_MODALITY_MODIFIER!>open<!> fun foo() {} override <!REDUNDANT_MODALITY_MODIFIER!>open<!> fun foo() {}
// error // error
final class Nested <!WRONG_MODIFIER_CONTAINING_DECLARATION!>final<!> class Nested
} }
// Derived abstract class // Derived abstract class
abstract class AbstractDerived1(override final val gav: Int) : Interface { abstract class AbstractDerived1(override final val gav: Int) : Interface {
@@ -4,7 +4,7 @@ annotation class Ann
var <!REDECLARATION!>x<!>: Int var <!REDECLARATION!>x<!>: Int
get() = 1 get() = 1
set(@Ann private x) { } set(@Ann <!WRONG_MODIFIER_TARGET!>private<!> x) { }
var <!REDECLARATION!>x<!>: String = "" var <!REDECLARATION!>x<!>: String = ""
@@ -339,6 +339,14 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val INFIX_MODIFIER_REQUIRED by error<PsiElement> { val INFIX_MODIFIER_REQUIRED by error<PsiElement> {
parameter<FirNamedFunctionSymbol>("functionSymbol") parameter<FirNamedFunctionSymbol>("functionSymbol")
} }
val WRONG_MODIFIER_CONTAINING_DECLARATION by error<PsiElement> {
parameter<String>("modifier")
parameter<String>("target")
}
val DEPRECATED_MODIFIER_CONTAINING_DECLARATION by warning<PsiElement> {
parameter<String>("modifier")
parameter<String>("target")
}
} }
val INLINE_CLASSES by object : DiagnosticGroup("Inline classes") { val INLINE_CLASSES by object : DiagnosticGroup("Inline classes") {
@@ -264,6 +264,8 @@ object FirErrors {
val WRONG_MODIFIER_TARGET by error2<PsiElement, String, String>() val WRONG_MODIFIER_TARGET by error2<PsiElement, String, 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 DEPRECATED_MODIFIER_CONTAINING_DECLARATION by warning2<PsiElement, String, 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)
@@ -6,9 +6,13 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.*
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.Companion.classActualTargets
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.* import org.jetbrains.kotlin.fir.analysis.checkers.*
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticFactory2 import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticFactory2
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
@@ -54,12 +58,34 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
val reportedNodes = hashSetOf<FirModifier<*>>() val reportedNodes = hashSetOf<FirModifier<*>>()
val actualTargets = getActualTargetList(owner).defaultTargets val actualTargets = getActualTargetList(owner).defaultTargets
val parent = context.findClosest<FirDeclaration> {
it !is FirPrimaryConstructor &&
it !is FirProperty &&
it.source?.kind !is FirFakeSourceElementKind
}
val actualParents = when (parent) {
is FirAnonymousObject -> listOf(LOCAL_CLASS, CLASS)
is FirClass -> classActualTargets(
parent.classKind,
isInnerClass = (parent as? FirMemberDeclaration)?.isInner ?: false,
isCompanionObject = (parent as? FirRegularClass)?.isCompanion ?: false,
isLocalClass = parent.isLocal
)
is FirPropertyAccessor -> listOf(if (parent.isSetter) PROPERTY_SETTER else PROPERTY_GETTER)
is FirFunction -> listOf(FUNCTION)
is FirEnumEntry -> listOf(ENUM_ENTRY, PROPERTY, FIELD)
else -> listOf(FILE)
}
val modifiers = list.modifiers val modifiers = list.modifiers
for ((secondIndex, secondModifier) in modifiers.withIndex()) { for ((secondIndex, secondModifier) in modifiers.withIndex()) {
for (firstIndex in 0 until secondIndex) { for (firstIndex in 0 until secondIndex) {
checkCompatibilityType(modifiers[firstIndex], secondModifier, reporter, reportedNodes, owner, context) checkCompatibilityType(modifiers[firstIndex], secondModifier, reporter, reportedNodes, owner, context)
} }
if (secondModifier !in reportedNodes) { if (secondModifier !in reportedNodes) {
val modifierSource = secondModifier.source
val modifierType = getKeywordType(secondModifier)
when { when {
!checkTarget(modifierSource, modifierType, actualTargets, parent, context, reporter) -> reportedNodes += secondModifier !checkTarget(modifierSource, modifierType, actualTargets, parent, context, reporter) -> reportedNodes += secondModifier
!checkParent(modifierSource, modifierType, actualParents, context, reporter) -> reportedNodes += secondModifier !checkParent(modifierSource, modifierType, actualParents, context, reporter) -> reportedNodes += secondModifier
@@ -146,14 +172,13 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
} }
private fun checkTarget( private fun checkTarget(
modifier: FirModifier<*>, modifierSource: FirSourceElement,
modifierType: KeywordType,
actualTargets: List<KotlinTarget>, actualTargets: List<KotlinTarget>,
parent: FirDeclaration?, parent: FirDeclaration?,
context: CheckerContext, context: CheckerContext,
reporter: DiagnosticReporter reporter: DiagnosticReporter
): Boolean { ): Boolean {
val modifierType = getKeywordType(modifier)
fun checkModifier(factory: FirDiagnosticFactory2<String, String>): Boolean { fun checkModifier(factory: FirDiagnosticFactory2<String, String>): Boolean {
val map = when (factory) { val map = when (factory) {
FirErrors.WRONG_MODIFIER_TARGET -> possibleTargetMap FirErrors.WRONG_MODIFIER_TARGET -> possibleTargetMap
@@ -168,7 +193,7 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
} }
if (checkResult) { if (checkResult) {
reporter.reportOn( reporter.reportOn(
modifier.source, modifierSource,
factory, factory,
modifierType.render(), modifierType.render(),
actualTargets.firstOrThis(), actualTargets.firstOrThis(),
@@ -193,7 +218,7 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
val deprecatedModifierReplacement = deprecatedModifierMap[modifierType] val deprecatedModifierReplacement = deprecatedModifierMap[modifierType]
if (deprecatedModifierReplacement != null) { if (deprecatedModifierReplacement != null) {
reporter.reportOn( reporter.reportOn(
modifier.source, modifierSource,
FirErrors.DEPRECATED_MODIFIER, FirErrors.DEPRECATED_MODIFIER,
modifierType.render(), modifierType.render(),
deprecatedModifierReplacement.render(), deprecatedModifierReplacement.render(),
@@ -206,6 +231,39 @@ object FirModifierChecker : FirBasicDeclarationChecker() {
return true return true
} }
private fun checkParent(
modifierSource: FirSourceElement,
modifierType: KeywordType,
actualParents: List<KotlinTarget>,
context: CheckerContext,
reporter: DiagnosticReporter
): Boolean {
val deprecatedParents = deprecatedParentTargetMap[modifierType]
if (deprecatedParents != null && actualParents.any { it in deprecatedParents }) {
reporter.reportOn(
modifierSource,
FirErrors.DEPRECATED_MODIFIER_CONTAINING_DECLARATION,
modifierType.render(),
actualParents.firstOrThis(),
context
)
return true
}
val possibleParentPredicate = possibleParentTargetPredicateMap[modifierType] ?: return true
if (actualParents.any { possibleParentPredicate.isAllowed(it, context.session.languageVersionSettings) }) return true
reporter.reportOn(
modifierSource,
FirErrors.WRONG_MODIFIER_CONTAINING_DECLARATION,
modifierType.render(),
actualParents.firstOrThis(),
context
)
return false
}
private fun List<KotlinTarget>.firstOrThis(): String { private fun List<KotlinTarget>.firstOrThis(): String {
return firstOrNull()?.description ?: "this" return firstOrNull()?.description ?: "this"
} }
@@ -126,6 +126,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_IN_INT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_NOT_TO_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_NOT_TO_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_MODIFIER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_MODIFIER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_MODIFIER_CONTAINING_DECLARATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_MODIFIER_FOR_TARGET import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_MODIFIER_FOR_TARGET
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_MODIFIER_PAIR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_MODIFIER_PAIR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_SINCE_KOTLIN_OUTSIDE_KOTLIN_SUBPACKAGE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_SINCE_KOTLIN_OUTSIDE_KOTLIN_SUBPACKAGE
@@ -465,6 +466,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_ANNOTATION_
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_GETTER_RETURN_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_GETTER_RETURN_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_INVOCATION_KIND import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_INVOCATION_KIND
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_MODIFIER_CONTAINING_DECLARATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_MODIFIER_TARGET import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_MODIFIER_TARGET
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
@@ -737,6 +739,8 @@ class FirDefaultErrorMessages {
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}''", 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(DEPRECATED_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is deprecated inside ''{1}''", 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")
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.declarations.builder package org.jetbrains.kotlin.fir.declarations.builder
import kotlin.contracts.* import kotlin.contracts.*
import org.jetbrains.kotlin.fir.FirImplementationDetail
import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
@@ -55,6 +56,7 @@ class FirPrimaryConstructorBuilder : FirAbstractConstructorBuilder, FirAnnotatio
override var delegatedConstructor: FirDelegatedConstructorCall? = null override var delegatedConstructor: FirDelegatedConstructorCall? = null
override var body: FirBlock? = null override var body: FirBlock? = null
@OptIn(FirImplementationDetail::class)
override fun build(): FirConstructor { override fun build(): FirConstructor {
return FirPrimaryConstructor( return FirPrimaryConstructor(
source, source,
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.declarations.impl package org.jetbrains.kotlin.fir.declarations.impl
import org.jetbrains.kotlin.fir.FirImplementationDetail
import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.declarations.DeprecationsPerUseSite import org.jetbrains.kotlin.fir.declarations.DeprecationsPerUseSite
@@ -30,7 +31,7 @@ import org.jetbrains.kotlin.fir.visitors.*
* DO NOT MODIFY IT MANUALLY * DO NOT MODIFY IT MANUALLY
*/ */
internal class FirPrimaryConstructor( class FirPrimaryConstructor @FirImplementationDetail constructor(
override val source: FirSourceElement?, override val source: FirSourceElement?,
override val moduleData: FirModuleData, override val moduleData: FirModuleData,
@Volatile @Volatile
@@ -22,6 +22,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
} }
impl(constructor, "FirPrimaryConstructor") { impl(constructor, "FirPrimaryConstructor") {
publicImplementation()
defaultTrue("isPrimary", withGetter = true) defaultTrue("isPrimary", withGetter = true)
} }
@@ -1,23 +0,0 @@
// !LANGUAGE: +NestedClassesInAnnotations
annotation class Foo {
class Nested
inner class Inner
enum class E { A, B }
object O
interface I
annotation class Anno(val e: E)
companion object {
val x = 1
const val y = ""
}
<!ANNOTATION_CLASS_MEMBER!>constructor(s: Int) {}<!>
<!ANNOTATION_CLASS_MEMBER!>init {}<!>
<!ANNOTATION_CLASS_MEMBER!>fun function() {}<!>
<!ANNOTATION_CLASS_MEMBER!>val property get() = Unit<!>
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +NestedClassesInAnnotations // !LANGUAGE: +NestedClassesInAnnotations
annotation class Foo { annotation class Foo {
@@ -1,43 +0,0 @@
// !DIAGNOSTICS: -DUPLICATE_CLASS_NAMES
package Jet86
class A {
companion <!REDECLARATION!>object<!> {
val x = 1
}
<!MANY_COMPANION_OBJECTS!>companion<!> <!REDECLARATION!>object<!> {
val x = 1
}
}
class AA {
companion object {
val x = 1
}
<!MANY_COMPANION_OBJECTS!>companion<!> object A {
val x = 1
}
<!MANY_COMPANION_OBJECTS!>companion<!> object AA {
val x = 1
}
}
class B() {
val x = 12
}
object b {
companion object {
val x = 1
} // error
}
val a = A.x
val c = B.<!UNRESOLVED_REFERENCE!>x<!>
val d = b.<!UNRESOLVED_REFERENCE!>x<!>
val s = <!NO_COMPANION_OBJECT!>System<!> // error
fun test() {
System.out.println()
java.lang.System.out.println()
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -DUPLICATE_CLASS_NAMES // !DIAGNOSTICS: -DUPLICATE_CLASS_NAMES
package Jet86 package Jet86
@@ -1,9 +0,0 @@
fun test() {
class A {
companion object {}
}
object {
companion object {}
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
fun test() { fun test() {
class A { class A {
<!WRONG_MODIFIER_CONTAINING_DECLARATION!>companion<!> object {} <!WRONG_MODIFIER_CONTAINING_DECLARATION!>companion<!> object {}
@@ -9,9 +9,9 @@ class A {
} }
object O { object O {
companion object A <!WRONG_MODIFIER_CONTAINING_DECLARATION!>companion<!> object A
<!MANY_COMPANION_OBJECTS!>companion<!> object B <!MANY_COMPANION_OBJECTS, WRONG_MODIFIER_CONTAINING_DECLARATION!>companion<!> object B
<!MANY_COMPANION_OBJECTS!>companion<!> object C <!MANY_COMPANION_OBJECTS, WRONG_MODIFIER_CONTAINING_DECLARATION!>companion<!> object C
} }
@@ -1,5 +0,0 @@
interface T {
final fun component1(): Int = 42
}
<!DATA_CLASS_OVERRIDE_CONFLICT!>data<!> class A(val x: Int) : T
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
interface T { interface T {
<!WRONG_MODIFIER_CONTAINING_DECLARATION!>final<!> fun component1(): Int = 42 <!WRONG_MODIFIER_CONTAINING_DECLARATION!>final<!> fun component1(): Int = 42
} }
@@ -1 +0,0 @@
<!INCOMPATIBLE_MODIFIERS!>inner<!> <!INCOMPATIBLE_MODIFIERS!>data<!> class Outer(val x: Int)
@@ -1 +1,2 @@
// FIR_IDENTICAL
<!WRONG_MODIFIER_CONTAINING_DECLARATION!>inner<!> <!INCOMPATIBLE_MODIFIERS!>data<!> class Outer(val x: Int) <!WRONG_MODIFIER_CONTAINING_DECLARATION!>inner<!> <!INCOMPATIBLE_MODIFIERS!>data<!> class Outer(val x: Int)
@@ -1,17 +0,0 @@
//KT-2397 Prohibit final methods in traits with no implementation
package a
interface T {
final fun foo()
final val b : Int
final fun bar() {}
final val c : Int
get() = 42
final val d = <!PROPERTY_INITIALIZER_IN_INTERFACE!>1<!>
}
class A {
<!NON_ABSTRACT_FUNCTION_WITH_NO_BODY!>final fun foo()<!>
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
//KT-2397 Prohibit final methods in traits with no implementation //KT-2397 Prohibit final methods in traits with no implementation
package a package a
@@ -1,10 +0,0 @@
package d
<!WRONG_MODIFIER_TARGET!>override<!> val f : ()-> Int = { 12 }
fun test() {
f()
}
var g: Int = 1
protected set(i: Int) {}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
package d package d
<!WRONG_MODIFIER_TARGET!>override<!> val f : ()-> Int = { 12 } <!WRONG_MODIFIER_TARGET!>override<!> val f : ()-> Int = { 12 }
@@ -1,11 +0,0 @@
enum class E {
FIRST,
SECOND {
companion object {
fun foo() = 42
}
};
}
fun f() = E.SECOND.<!UNRESOLVED_REFERENCE!>foo<!>()
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
enum class E { enum class E {
FIRST, FIRST,
@@ -16,7 +16,7 @@ inline class A9(final val x: Int)
class B1 { class B1 {
companion object { companion object {
inline class C1(val x: Int) inline class C1(val x: Int)
inner <!INLINE_CLASS_NOT_TOP_LEVEL!>inline<!> class C11(val x: Int) <!WRONG_MODIFIER_CONTAINING_DECLARATION!>inner<!> <!INLINE_CLASS_NOT_TOP_LEVEL!>inline<!> class C11(val x: Int)
} }
inline class C2(val x: Int) inline class C2(val x: Int)
@@ -25,7 +25,7 @@ class B1 {
object B2 { object B2 {
inline class C3(val x: Int) inline class C3(val x: Int)
inner <!INLINE_CLASS_NOT_TOP_LEVEL!>inline<!> class C31(val x: Int) <!WRONG_MODIFIER_CONTAINING_DECLARATION!>inner<!> <!INLINE_CLASS_NOT_TOP_LEVEL!>inline<!> class C31(val x: Int)
} }
fun foo() { fun foo() {
@@ -4,11 +4,11 @@ class A<T> {
class B { class B {
fun test() { fun test() {
class C<W>() : P<W, <!UNRESOLVED_REFERENCE!>T<!>> { class C<W>() : P<W, <!UNRESOLVED_REFERENCE!>T<!>> {
companion object : P<W, <!UNRESOLVED_REFERENCE!>T<!>> { <!WRONG_MODIFIER_CONTAINING_DECLARATION!>companion<!> object : P<W, <!UNRESOLVED_REFERENCE!>T<!>> {
} }
inner class D : P<W, <!UNRESOLVED_REFERENCE!>T<!>> inner class D : P<W, <!UNRESOLVED_REFERENCE!>T<!>>
} }
} }
} }
} }
@@ -2,7 +2,7 @@
enum class Enum { enum class Enum {
ENTRY_WITH_CLASS { ENTRY_WITH_CLASS {
inner class TestInner <!WRONG_MODIFIER_CONTAINING_DECLARATION!>inner<!> class TestInner
<!NESTED_CLASS_NOT_ALLOWED!>class TestNested<!> <!NESTED_CLASS_NOT_ALLOWED!>class TestNested<!>
@@ -14,6 +14,6 @@ enum class Enum {
OTHER_ENTRY OTHER_ENTRY
} }
companion object {} <!WRONG_MODIFIER_CONTAINING_DECLARATION!>companion<!> object {}
} }
} }
@@ -14,6 +14,6 @@ enum class Enum {
OTHER_ENTRY OTHER_ENTRY
} }
companion object {} <!WRONG_MODIFIER_CONTAINING_DECLARATION!>companion<!> object {}
} }
} }
@@ -14,6 +14,6 @@ enum class Enum {
OTHER_ENTRY OTHER_ENTRY
} }
companion object {} <!WRONG_MODIFIER_CONTAINING_DECLARATION!>companion<!> object {}
} }
} }
@@ -1,12 +0,0 @@
annotation class My(
public val x: Int,
protected val y: Int,
internal val z: Int,
private val w: Int
)
open class Your {
open val x: Int = 0
}
annotation class His(override val x: Int): <!SUPERTYPES_FOR_ANNOTATION_CLASS!>Your()<!>
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
annotation class My( annotation class My(
public val x: Int, public val x: Int,
<!WRONG_MODIFIER_CONTAINING_DECLARATION!>protected<!> val y: Int, <!WRONG_MODIFIER_CONTAINING_DECLARATION!>protected<!> val y: Int,
@@ -1,7 +0,0 @@
interface My {
internal val x: Int
internal val xxx: Int
get() = 0
internal fun foo(): Int
internal fun bar() = 42
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
interface My { interface My {
<!WRONG_MODIFIER_CONTAINING_DECLARATION!>internal<!> val x: Int <!WRONG_MODIFIER_CONTAINING_DECLARATION!>internal<!> val x: Int
<!WRONG_MODIFIER_CONTAINING_DECLARATION!>internal<!> val xxx: Int <!WRONG_MODIFIER_CONTAINING_DECLARATION!>internal<!> val xxx: Int
@@ -2,11 +2,11 @@
fun f(vararg x: Int) {} fun f(vararg x: Int) {}
val inVal: (vararg x: Int)->Unit = {} val inVal: (<!WRONG_MODIFIER_CONTAINING_DECLARATION!>vararg<!> x: Int)->Unit = {}
fun inParam(fn: (vararg x: Int)->Unit) {} fun inParam(fn: (<!WRONG_MODIFIER_CONTAINING_DECLARATION!>vararg<!> x: Int)->Unit) {}
fun inParamNested(fn1: (fn2: (vararg n: Int)->Unit)->Unit) {} fun inParamNested(fn1: (fn2: (<!WRONG_MODIFIER_CONTAINING_DECLARATION!>vararg<!> n: Int)->Unit)->Unit) {}
fun inReturn(): (vararg x: Int)->Unit = {} fun inReturn(): (vararg x: Int)->Unit = {}
@@ -16,7 +16,7 @@ class A : (vararg Int)->Unit {
} }
val prop: (vararg x: Int)->Unit val prop: (vararg x: Int)->Unit
get(): (vararg x: Int)->Unit = {} get(): (<!WRONG_MODIFIER_CONTAINING_DECLARATION, WRONG_MODIFIER_CONTAINING_DECLARATION!>vararg<!> x: Int)->Unit = {}
} }
val allProhibited: (<!REDUNDANT_MODIFIER, WRONG_MODIFIER_TARGET!>abstract<!> val allProhibited: (<!REDUNDANT_MODIFIER, WRONG_MODIFIER_TARGET!>abstract<!>
@@ -44,7 +44,7 @@ val allProhibited: (<!REDUNDANT_MODIFIER, WRONG_MODIFIER_TARGET!>abstract<!>
<!WRONG_MODIFIER_TARGET!>reified<!> <!WRONG_MODIFIER_TARGET!>reified<!>
<!INCOMPATIBLE_MODIFIERS!>sealed<!> <!INCOMPATIBLE_MODIFIERS!>sealed<!>
<!WRONG_MODIFIER_TARGET!>tailrec<!> <!WRONG_MODIFIER_TARGET!>tailrec<!>
vararg <!WRONG_MODIFIER_CONTAINING_DECLARATION!>vararg<!>
x: Int)->Unit = {} x: Int)->Unit = {}
@@ -1,12 +0,0 @@
interface My {
<!PRIVATE_PROPERTY_IN_INTERFACE!>private<!> val x: Int
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>abstract<!> val xx: Int
private val xxx: Int
get() = 0
final val y: Int
final val yy: Int
get() = 1
<!PRIVATE_FUNCTION_WITH_NO_BODY!>private<!> fun foo(): Int
// ok
private fun bar() = 42
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
interface My { interface My {
<!PRIVATE_PROPERTY_IN_INTERFACE!>private<!> val x: Int <!PRIVATE_PROPERTY_IN_INTERFACE!>private<!> val x: Int
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>abstract<!> val xx: Int <!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>abstract<!> val xx: Int
@@ -1,21 +0,0 @@
class My(protected val x: Int) {
class Her(protected val x: Int)
inner class Its(protected val x: Int)
}
object Your {
protected fun foo() = 3
}
annotation class His(protected val x: Int)
enum class Our(protected val x: Int) {
FIRST(42) {
protected fun foo() = 13
}
}
interface Their {
protected fun foo() = 7
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class My(protected val x: Int) { class My(protected val x: Int) {
class Her(protected val x: Int) class Her(protected val x: Int)
+3 -3
View File
@@ -6,7 +6,7 @@ open class C {
} }
interface T { interface T {
protected fun foo() {} <!WRONG_MODIFIER_CONTAINING_DECLARATION!>protected<!> fun foo() {}
} }
class G : C(), T { class G : C(), T {
@@ -18,7 +18,7 @@ open class A {
} }
interface B { interface B {
protected fun foo() {} <!WRONG_MODIFIER_CONTAINING_DECLARATION!>protected<!> fun foo() {}
} }
interface D { interface D {
@@ -27,4 +27,4 @@ interface D {
class E : A(), B, D { class E : A(), B, D {
override fun foo() {} override fun foo() {}
} }
@@ -3,8 +3,8 @@
//FILE:a.kt //FILE:a.kt
package test_visibility package test_visibility
protected class ProtectedClass <!WRONG_MODIFIER_CONTAINING_DECLARATION!>protected<!> class ProtectedClass
protected interface ProtectedTrait <!WRONG_MODIFIER_CONTAINING_DECLARATION!>protected<!> interface ProtectedTrait
<!WRONG_MODIFIER_TARGET!>protected<!> val protected_val : Int = 4 <!WRONG_MODIFIER_TARGET!>protected<!> val protected_val : Int = 4
<!WRONG_MODIFIER_TARGET!>protected<!> fun protected_fun() {} <!WRONG_MODIFIER_TARGET!>protected<!> fun protected_fun() {}
@@ -1,6 +1,6 @@
class My { class My {
var x: String = "" var x: String = ""
set(vararg value) { set(<!WRONG_MODIFIER_CONTAINING_DECLARATION!>vararg<!> value) {
x = <!ASSIGNMENT_TYPE_MISMATCH!>value<!> x = <!ASSIGNMENT_TYPE_MISMATCH!>value<!>
} }
} }
@@ -1,20 +0,0 @@
interface Test<in I, out O> {
val internal_val: <!TYPE_VARIANCE_CONFLICT!>I<!>
public val public_val: <!TYPE_VARIANCE_CONFLICT!>I<!>
protected val protected_val: <!TYPE_VARIANCE_CONFLICT!>I<!>
<!PRIVATE_PROPERTY_IN_INTERFACE!>private<!> val private_val: I
var interlan_private_set: <!TYPE_VARIANCE_CONFLICT!>O<!>
<!PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY!>private<!> set
public var public_private_set: <!TYPE_VARIANCE_CONFLICT!>O<!>
<!PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY!>private<!> set
protected var protected_private_set: <!TYPE_VARIANCE_CONFLICT!>O<!>
<!PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY!>private<!> set
<!PRIVATE_PROPERTY_IN_INTERFACE!>private<!> var private_private_set: O
private set
fun internal_fun(i: <!TYPE_VARIANCE_CONFLICT!>O<!>) : <!TYPE_VARIANCE_CONFLICT!>I<!>
public fun public_fun(i: <!TYPE_VARIANCE_CONFLICT!>O<!>) : <!TYPE_VARIANCE_CONFLICT!>I<!>
protected fun protected_fun(i: <!TYPE_VARIANCE_CONFLICT!>O<!>) : <!TYPE_VARIANCE_CONFLICT!>I<!>
<!PRIVATE_FUNCTION_WITH_NO_BODY!>private<!> fun private_fun(i: O) : I
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
interface Test<in I, out O> { interface Test<in I, out O> {
val internal_val: <!TYPE_VARIANCE_CONFLICT!>I<!> val internal_val: <!TYPE_VARIANCE_CONFLICT!>I<!>
public val public_val: <!TYPE_VARIANCE_CONFLICT!>I<!> public val public_val: <!TYPE_VARIANCE_CONFLICT!>I<!>
@@ -1083,6 +1083,22 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token, token,
) )
} }
add(FirErrors.WRONG_MODIFIER_CONTAINING_DECLARATION) { firDiagnostic ->
WrongModifierContainingDeclarationImpl(
firDiagnostic.a,
firDiagnostic.b,
firDiagnostic as FirPsiDiagnostic,
token,
)
}
add(FirErrors.DEPRECATED_MODIFIER_CONTAINING_DECLARATION) { firDiagnostic ->
DeprecatedModifierContainingDeclarationImpl(
firDiagnostic.a,
firDiagnostic.b,
firDiagnostic as FirPsiDiagnostic,
token,
)
}
add(FirErrors.INLINE_CLASS_NOT_TOP_LEVEL) { firDiagnostic -> add(FirErrors.INLINE_CLASS_NOT_TOP_LEVEL) { firDiagnostic ->
InlineClassNotTopLevelImpl( InlineClassNotTopLevelImpl(
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
@@ -783,6 +783,18 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract val functionSymbol: KtFunctionLikeSymbol abstract val functionSymbol: KtFunctionLikeSymbol
} }
abstract class WrongModifierContainingDeclaration : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = WrongModifierContainingDeclaration::class
abstract val modifier: String
abstract val target: String
}
abstract class DeprecatedModifierContainingDeclaration : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = DeprecatedModifierContainingDeclaration::class
abstract val modifier: String
abstract val target: String
}
abstract class InlineClassNotTopLevel : KtFirDiagnostic<KtDeclaration>() { abstract class InlineClassNotTopLevel : KtFirDiagnostic<KtDeclaration>() {
override val diagnosticClass get() = InlineClassNotTopLevel::class override val diagnosticClass get() = InlineClassNotTopLevel::class
} }
@@ -1243,6 +1243,24 @@ internal class InfixModifierRequiredImpl(
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
} }
internal class WrongModifierContainingDeclarationImpl(
override val modifier: String,
override val target: String,
firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.WrongModifierContainingDeclaration(), KtAbstractFirDiagnostic<PsiElement> {
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
}
internal class DeprecatedModifierContainingDeclarationImpl(
override val modifier: String,
override val target: String,
firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.DeprecatedModifierContainingDeclaration(), KtAbstractFirDiagnostic<PsiElement> {
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
}
internal class InlineClassNotTopLevelImpl( internal class InlineClassNotTopLevelImpl(
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,