[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
@@ -7,7 +7,7 @@ annotation class A
@A
open class B1 {
@A
private open fun foo() {}
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>open<!> fun foo() {}
}
class D1 : B1() {
@@ -2,7 +2,7 @@ interface SuperInterface
open class SuperClass
abstract data class Base(val x: Int)
<!INCOMPATIBLE_MODIFIERS!>abstract<!> <!INCOMPATIBLE_MODIFIERS!>data<!> class Base(val x: Int)
class Derived: Base(42)
@@ -1,3 +0,0 @@
class Outer {
inner data class Inner(val x: Int)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class Outer {
<!INCOMPATIBLE_MODIFIERS!>inner<!> <!INCOMPATIBLE_MODIFIERS!>data<!> class Inner(val x: Int)
}
@@ -1 +1 @@
inner data class Outer(val x: Int)
<!INCOMPATIBLE_MODIFIERS!>inner<!> <!INCOMPATIBLE_MODIFIERS!>data<!> class Outer(val x: Int)
@@ -1,4 +0,0 @@
sealed data class My(val x: Int) {
object Your: My(1)
class His(y: Int): My(y)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
<!INCOMPATIBLE_MODIFIERS!>sealed<!> <!INCOMPATIBLE_MODIFIERS!>data<!> class My(val x: Int) {
object Your: My(1)
class His(y: Int): My(y)
@@ -30,4 +30,4 @@ open inline class D1(val x: Int)
abstract inline class D2(val x: Int)
sealed inline class D3(val x: Int)
inline data class D4(val x: String)
<!INCOMPATIBLE_MODIFIERS!>inline<!> <!INCOMPATIBLE_MODIFIERS!>data<!> class D4(val x: String)
@@ -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
}
}
@@ -1,13 +1,13 @@
// !LANGUAGE: +MultiPlatformProjects
header impl class First
<!INCOMPATIBLE_MODIFIERS!>header<!> <!INCOMPATIBLE_MODIFIERS!>impl<!> class First
header expect class Second
<!INCOMPATIBLE_MODIFIERS!>header<!> <!INCOMPATIBLE_MODIFIERS!>expect<!> class Second
header actual class Third
<!INCOMPATIBLE_MODIFIERS!>header<!> <!INCOMPATIBLE_MODIFIERS!>actual<!> class Third
impl expect class Fourth
<!INCOMPATIBLE_MODIFIERS!>impl<!> <!INCOMPATIBLE_MODIFIERS!>expect<!> class Fourth
impl actual class Fifth
<!INCOMPATIBLE_MODIFIERS!>impl<!> <!INCOMPATIBLE_MODIFIERS!>actual<!> class Fifth
expect actual class Sixth
<!INCOMPATIBLE_MODIFIERS!>expect<!> <!INCOMPATIBLE_MODIFIERS!>actual<!> class Sixth
@@ -11,7 +11,7 @@ public abstract class TestBug1() {
position(m1().second)
}
private abstract fun m1(): Pair<Int, Int>
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>abstract<!> fun m1(): Pair<Int, Int>
private fun position(p: Int) {}
@@ -19,6 +19,6 @@ public abstract class TestBug1() {
//from library
public class Pair<out A, out B> (
public val first: A,
public val second: B
public val first: A,
public val second: B
)
@@ -14,7 +14,7 @@ class C : A() {
//------------
open class D {
private open fun self() : D = this
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>open<!> fun self() : D = this
}
class E : D() {
+1 -1
View File
@@ -32,7 +32,7 @@ class E : C(), T {
}
class F : C(), T {
private override fun foo() {}
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>override<!> fun foo() {}
}
class G : C(), T {
@@ -1,3 +0,0 @@
final sealed class Base {
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
<!INCOMPATIBLE_MODIFIERS!>final<!> <!INCOMPATIBLE_MODIFIERS!>sealed<!> class Base {
}
@@ -1,3 +0,0 @@
open sealed class Base {
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
<!INCOMPATIBLE_MODIFIERS!>open<!> <!INCOMPATIBLE_MODIFIERS!>sealed<!> class Base {
}
@@ -1,3 +0,0 @@
abstract sealed class Base {
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
<!REDUNDANT_MODIFIER!>abstract<!> sealed class Base {
}
@@ -4,7 +4,7 @@ interface Allowed
open class NotAllowed
abstract data class Base(val x: Int)
<!INCOMPATIBLE_MODIFIERS!>abstract<!> <!INCOMPATIBLE_MODIFIERS!>data<!> class Base(val x: Int)
class Derived: Base(42)