[FIR] Support 4 diagnostics for pairs of modifiers

In particular, this commit includes:
* Attempt to abstract access to FirSourceElement via FirModifier
* Add more visit functions to DeclarationCheckersDiagnosticComponent
* Add messages+factories for 4 modifier-related errors and warnings
* Introduce FirModifierChecker
This commit is contained in:
FenstonSingel
2020-03-27 02:10:26 +03:00
committed by Mikhail Glukhikh
parent 311a91af79
commit b7d8e879a6
42 changed files with 656 additions and 122 deletions
@@ -2,9 +2,9 @@
package illegal_modifiers
abstract class A() {
abstract final fun f()
abstract open fun g()
final open fun h() {}
<!INCOMPATIBLE_MODIFIERS!>abstract<!> <!INCOMPATIBLE_MODIFIERS!>final<!> fun f()
abstract <!REDUNDANT_MODIFIER!>open<!> fun g()
<!INCOMPATIBLE_MODIFIERS!>final<!> <!INCOMPATIBLE_MODIFIERS!>open<!> fun h() {}
open var r: String
get
@@ -21,8 +21,8 @@ class FinalClass() {
open set(v: Int) {}
}
private public class C
private public object D
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>public<!> class C
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>public<!> object D
//A sample annotation to check annotation usage in parameters.
annotation class annotated(val text: String = "not given")
@@ -32,8 +32,8 @@ class LegalModifier(val a: Int, @annotated private var b: String, @annotated var
//Check illegal modifier in constructor parameters
class IllegalModifiers1(
in
out
<!INCOMPATIBLE_MODIFIERS!>in<!>
<!INCOMPATIBLE_MODIFIERS!>out<!>
reified
enum
private
@@ -41,7 +41,7 @@ class IllegalModifiers1(
a: Int)
//Check multiple illegal modifiers in constructor
class IllegalModifiers2(private abstract a: Int)
class IllegalModifiers2(<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>abstract<!> a: Int)
//Check annotations with illegal modifiers in constructor
@@ -65,10 +65,10 @@ abstract class IllegalModifiers5() {
private fun qux() {
//Check illegal modifier in catch block
try {} catch (in out reified enum public e: Exception) {}
try {} catch (<!INCOMPATIBLE_MODIFIERS!>in<!> <!INCOMPATIBLE_MODIFIERS!>out<!> reified enum public e: Exception) {}
//Check multiple illegal modifiers in catch block
try {} catch (in out reified enum abstract public e: Exception) {}
try {} catch (<!INCOMPATIBLE_MODIFIERS!>in<!> <!INCOMPATIBLE_MODIFIERS!>out<!> reified enum abstract public e: Exception) {}
//Check annotations with illegal modifiers
try {} catch (@annotated("a text") abstract public e: Exception) {}
@@ -92,24 +92,24 @@ abstract class IllegalModifiers6() {
// strange inappropriate modifiers usages
override
out
in
<!INCOMPATIBLE_MODIFIERS!>out<!>
<!INCOMPATIBLE_MODIFIERS!>in<!>
vararg
reified
class IllegalModifiers7() {
enum
inner
annotation
out
in
<!INCOMPATIBLE_MODIFIERS!>out<!>
<!INCOMPATIBLE_MODIFIERS!>in<!>
vararg
reified
val x = 1
enum
inner
annotation
out
in
<!INCOMPATIBLE_MODIFIERS!>out<!>
<!INCOMPATIBLE_MODIFIERS!>in<!>
vararg
reified
const
@@ -118,46 +118,46 @@ class IllegalModifiers7() {
// Secondary constructors
class IllegalModifiers8 {
abstract
<!INCOMPATIBLE_MODIFIERS!>abstract<!>
enum
open
<!INCOMPATIBLE_MODIFIERS, REDUNDANT_MODIFIER!>open<!>
inner
annotation
override
out
in
final
<!INCOMPATIBLE_MODIFIERS!>override<!>
<!INCOMPATIBLE_MODIFIERS!>out<!>
<!INCOMPATIBLE_MODIFIERS!>in<!>
<!INCOMPATIBLE_MODIFIERS!>final<!>
vararg
reified
const<!SYNTAX!><!>
<!INCOMPATIBLE_MODIFIERS!>const<!><!SYNTAX!><!>
constructor() {}
constructor(private enum abstract x: Int) {}
constructor(<!INCOMPATIBLE_MODIFIERS!>private<!> enum <!INCOMPATIBLE_MODIFIERS!>abstract<!> x: Int) {}
}
class IllegalModifiers9 {
private protected constructor() {}
private internal constructor(x: Int) {}
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>protected<!> constructor() {}
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>internal<!> constructor(x: Int) {}
}
// Illegal modifiers on primary constructor
class IllegalModifiers10
abstract
<!INCOMPATIBLE_MODIFIERS!>abstract<!>
enum
open
<!INCOMPATIBLE_MODIFIERS, REDUNDANT_MODIFIER!>open<!>
inner
annotation
override
out
in
final
<!INCOMPATIBLE_MODIFIERS!>override<!>
<!INCOMPATIBLE_MODIFIERS!>out<!>
<!INCOMPATIBLE_MODIFIERS!>in<!>
<!INCOMPATIBLE_MODIFIERS!>final<!>
vararg
reified
const constructor()
<!INCOMPATIBLE_MODIFIERS!>const<!> constructor()
class IllegalModifiers11 private protected constructor()
class IllegalModifiers11 <!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>protected<!> constructor()
class Outer {
inner sealed class Inner
<!INCOMPATIBLE_MODIFIERS!>inner<!> <!INCOMPATIBLE_MODIFIERS!>sealed<!> class Inner
}
@@ -15,9 +15,9 @@ object A {
class B(const val constructor: Int = 5)
abstract class C {
open const val x: Int = 6
<!INCOMPATIBLE_MODIFIERS!>open<!> <!INCOMPATIBLE_MODIFIERS!>const<!> val x: Int = 6
abstract const val y: Int = 7
<!INCOMPATIBLE_MODIFIERS!>abstract<!> <!INCOMPATIBLE_MODIFIERS!>const<!> val y: Int = 7
companion object {
const val inCompaionObject = 8
@@ -25,7 +25,7 @@ abstract class C {
}
object D : C() {
override const val x: Int = 9
<!INCOMPATIBLE_MODIFIERS!>override<!> <!INCOMPATIBLE_MODIFIERS!>const<!> val x: Int = 9
const val inObject = 10
@@ -1,8 +1,8 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE
interface Foo<T>
interface Foo1<in out T>
interface Foo2<in in T>
interface Foo1<<!INCOMPATIBLE_MODIFIERS!>in<!> <!INCOMPATIBLE_MODIFIERS!>out<!> T>
interface Foo2<in <!REPEATED_MODIFIER!>in<!> T>
fun test1(foo: Foo<in out Int>) = foo
fun test2(): Foo<in in Int> = throw Exception()
@@ -10,11 +10,11 @@ fun test2(): Foo<in in Int> = throw Exception()
fun test3() {
val f: Foo<out out out out Int>
class Bzz<in in T>
class Bzz<in <!REPEATED_MODIFIER!>in<!> T>
}
class A {
fun <out out T> bar() {
fun <out <!REPEATED_MODIFIER!>out<!> T> bar() {
}
}
@@ -8,13 +8,13 @@ fun gav(noinline x: (Int) -> Unit, crossinline y: (String) -> Int) {}
inline fun correct(noinline x: (Int) -> Unit, crossinline y: (String) -> Int) {}
inline fun incompatible(noinline crossinline x: () -> String) {}
inline fun incompatible(<!INCOMPATIBLE_MODIFIERS!>noinline<!> <!INCOMPATIBLE_MODIFIERS!>crossinline<!> x: () -> String) {}
class FunctionSubtype : () -> Unit {
override fun invoke() {}
}
inline fun functionSubtype(
noinline f: FunctionSubtype,
crossinline g: FunctionSubtype
noinline f: FunctionSubtype,
crossinline g: FunctionSubtype
) { }
@@ -19,30 +19,30 @@ class A : (vararg Int)->Unit {
get(): (vararg x: Int)->Unit = {}
}
val allProhibited: (abstract
val allProhibited: (<!INCOMPATIBLE_MODIFIERS, REDUNDANT_MODIFIER!>abstract<!>
annotation
companion
const
crossinline
data
<!INCOMPATIBLE_MODIFIERS!>const<!>
<!INCOMPATIBLE_MODIFIERS!>crossinline<!>
<!INCOMPATIBLE_MODIFIERS!>data<!>
enum
external
final
in
inline
inner
internal
<!INCOMPATIBLE_MODIFIERS!>final<!>
<!INCOMPATIBLE_MODIFIERS!>in<!>
<!INCOMPATIBLE_MODIFIERS!>inline<!>
<!INCOMPATIBLE_MODIFIERS!>inner<!>
<!INCOMPATIBLE_MODIFIERS!>internal<!>
lateinit
noinline
open
<!INCOMPATIBLE_MODIFIERS!>noinline<!>
<!INCOMPATIBLE_MODIFIERS, REDUNDANT_MODIFIER!>open<!>
operator
out
override
private
protected
public
<!INCOMPATIBLE_MODIFIERS!>out<!>
<!INCOMPATIBLE_MODIFIERS!>override<!>
<!INCOMPATIBLE_MODIFIERS!>private<!>
<!INCOMPATIBLE_MODIFIERS!>protected<!>
<!INCOMPATIBLE_MODIFIERS!>public<!>
reified
sealed
<!INCOMPATIBLE_MODIFIERS!>sealed<!>
tailrec
vararg
@@ -1,10 +1,10 @@
interface My {
open fun foo()
open fun bar() {}
open abstract fun baz(): Int
<!REDUNDANT_MODIFIER!>open<!> abstract fun baz(): Int
open val x: Int
open val y: String
get() = ""
open abstract val z: Double
<!REDUNDANT_MODIFIER!>open<!> abstract val z: Double
}
@@ -1,6 +1,6 @@
interface My {
private val x: Int
private abstract val xx: Int
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>abstract<!> val xx: Int
private val xxx: Int
get() = 0
final val y: Int
@@ -1,41 +1,41 @@
abstract abstract class Foo
public public class Bar
open open final class Baz {
private private fun foo() {}
abstract <!REPEATED_MODIFIER!>abstract<!> class Foo
public <!REPEATED_MODIFIER!>public<!> class Bar
<!INCOMPATIBLE_MODIFIERS!>open<!> <!REPEATED_MODIFIER!>open<!> <!INCOMPATIBLE_MODIFIERS!>final<!> class Baz {
private <!REPEATED_MODIFIER!>private<!> fun foo() {}
}
class Bzz(public public val q: Int = 1) {
public public val x: Int = 2
class Bzz(public <!REPEATED_MODIFIER!>public<!> val q: Int = 1) {
public <!REPEATED_MODIFIER!>public<!> val x: Int = 2
public val y: Int
public public get() = 3
public <!REPEATED_MODIFIER!>public<!> get() = 3
val z: Int
open final get() = 4
<!INCOMPATIBLE_MODIFIERS!>open<!> <!INCOMPATIBLE_MODIFIERS!>final<!> get() = 4
public public class B(public public val z: Int = 1) {
public public val y: Int = 2
public <!REPEATED_MODIFIER!>public<!> class B(public <!REPEATED_MODIFIER!>public<!> val z: Int = 1) {
public <!REPEATED_MODIFIER!>public<!> val y: Int = 2
public val x: Int
public public get() = 3
public <!REPEATED_MODIFIER!>public<!> get() = 3
}
public public object C {
public public val y: Int = 1
public public fun z(): Int = 1
public <!REPEATED_MODIFIER!>public<!> object C {
public <!REPEATED_MODIFIER!>public<!> val y: Int = 1
public <!REPEATED_MODIFIER!>public<!> fun z(): Int = 1
}
}
public public val bar: Int = 1
public <!REPEATED_MODIFIER!>public<!> val bar: Int = 1
public public fun foo(): Int = 1
public <!REPEATED_MODIFIER!>public<!> fun foo(): Int = 1
fun test() {
public public class B(public public val z: Int = 1) {
public public val y: Int = 2
public <!REPEATED_MODIFIER!>public<!> class B(public <!REPEATED_MODIFIER!>public<!> val z: Int = 1) {
public <!REPEATED_MODIFIER!>public<!> val y: Int = 2
public val x: Int
public public get() = 3
public <!REPEATED_MODIFIER!>public<!> get() = 3
}
}