'open' + 'private' and 'abstract' + 'private' are now incompatible for functions and properties #KT-9324 Fixed
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.resolve
|
package org.jetbrains.kotlin.resolve
|
||||||
|
|
||||||
import com.intellij.lang.ASTNode
|
import com.intellij.lang.ASTNode
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.tree.TokenSet
|
import com.intellij.psi.tree.TokenSet
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||||
@@ -30,12 +31,20 @@ import org.jetbrains.kotlin.psi.*
|
|||||||
|
|
||||||
public object ModifierCheckerCore {
|
public object ModifierCheckerCore {
|
||||||
private enum class Compatibility {
|
private enum class Compatibility {
|
||||||
|
// modifier pair is compatible: ok (default)
|
||||||
COMPATIBLE,
|
COMPATIBLE,
|
||||||
|
// second is redundant to first: warning
|
||||||
REDUNDANT,
|
REDUNDANT,
|
||||||
|
// first is redundant to second: warning
|
||||||
REVERSE_REDUNDANT,
|
REVERSE_REDUNDANT,
|
||||||
|
// error
|
||||||
REPEATED,
|
REPEATED,
|
||||||
|
// pair is deprecated, will become incompatible: warning
|
||||||
DEPRECATED,
|
DEPRECATED,
|
||||||
INCOMPATIBLE
|
// pair is incompatible: error
|
||||||
|
INCOMPATIBLE,
|
||||||
|
// same but only for functions / properties: error
|
||||||
|
COMPATIBLE_FOR_CLASSES_ONLY
|
||||||
}
|
}
|
||||||
|
|
||||||
private val possibleTargetMap = mapOf<JetModifierKeywordToken, Set<KotlinTarget>>(
|
private val possibleTargetMap = mapOf<JetModifierKeywordToken, Set<KotlinTarget>>(
|
||||||
@@ -121,6 +130,9 @@ public object ModifierCheckerCore {
|
|||||||
|
|
||||||
// private is incompatible with override
|
// private is incompatible with override
|
||||||
result += incompatibilityRegister(PRIVATE_KEYWORD, OVERRIDE_KEYWORD)
|
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)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +158,9 @@ public object ModifierCheckerCore {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun compatibilityForClassesRegister(vararg list: JetModifierKeywordToken) =
|
||||||
|
compatibilityRegister(Compatibility.COMPATIBLE_FOR_CLASSES_ONLY, *list)
|
||||||
|
|
||||||
private fun incompatibilityRegister(vararg list: JetModifierKeywordToken) = compatibilityRegister(Compatibility.INCOMPATIBLE, *list)
|
private fun incompatibilityRegister(vararg list: JetModifierKeywordToken) = compatibilityRegister(Compatibility.INCOMPATIBLE, *list)
|
||||||
|
|
||||||
private fun deprecationRegister(vararg list: JetModifierKeywordToken) = compatibilityRegister(Compatibility.DEPRECATED, *list)
|
private fun deprecationRegister(vararg list: JetModifierKeywordToken) = compatibilityRegister(Compatibility.DEPRECATED, *list)
|
||||||
@@ -159,7 +174,11 @@ public object ModifierCheckerCore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkCompatibility(trace: BindingTrace, firstNode: ASTNode, secondNode: ASTNode, incorrectNodes: MutableSet<ASTNode>) {
|
private fun checkCompatibility(trace: BindingTrace,
|
||||||
|
firstNode: ASTNode,
|
||||||
|
secondNode: ASTNode,
|
||||||
|
owner: PsiElement,
|
||||||
|
incorrectNodes: MutableSet<ASTNode>) {
|
||||||
val first = firstNode.elementType as JetModifierKeywordToken
|
val first = firstNode.elementType as JetModifierKeywordToken
|
||||||
val second = secondNode.elementType as JetModifierKeywordToken
|
val second = secondNode.elementType as JetModifierKeywordToken
|
||||||
val compatibility = compatibility(first, second)
|
val compatibility = compatibility(first, second)
|
||||||
@@ -176,7 +195,10 @@ public object ModifierCheckerCore {
|
|||||||
trace.report(Errors.DEPRECATED_MODIFIER_PAIR.on(firstNode.psi, first, second))
|
trace.report(Errors.DEPRECATED_MODIFIER_PAIR.on(firstNode.psi, first, second))
|
||||||
trace.report(Errors.DEPRECATED_MODIFIER_PAIR.on(secondNode.psi, second, first))
|
trace.report(Errors.DEPRECATED_MODIFIER_PAIR.on(secondNode.psi, second, first))
|
||||||
}
|
}
|
||||||
Compatibility.INCOMPATIBLE -> {
|
Compatibility.COMPATIBLE_FOR_CLASSES_ONLY, Compatibility.INCOMPATIBLE -> {
|
||||||
|
if (compatibility == Compatibility.COMPATIBLE_FOR_CLASSES_ONLY) {
|
||||||
|
if (owner is JetClassOrObject) return
|
||||||
|
}
|
||||||
if (incorrectNodes.add(firstNode)) {
|
if (incorrectNodes.add(firstNode)) {
|
||||||
trace.report(Errors.INCOMPATIBLE_MODIFIERS.on(firstNode.psi, first, second))
|
trace.report(Errors.INCOMPATIBLE_MODIFIERS.on(firstNode.psi, first, second))
|
||||||
}
|
}
|
||||||
@@ -234,7 +256,7 @@ public object ModifierCheckerCore {
|
|||||||
if (first == second) {
|
if (first == second) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
checkCompatibility(trace, first, second, incorrectNodes)
|
checkCompatibility(trace, first, second, list.owner, incorrectNodes)
|
||||||
}
|
}
|
||||||
if (second !in incorrectNodes) {
|
if (second !in incorrectNodes) {
|
||||||
if (!checkTarget(trace, second, actualTargets)) {
|
if (!checkTarget(trace, second, actualTargets)) {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class IllegalModifiers1(
|
|||||||
<!UNUSED_PARAMETER!>a<!>: Int)
|
<!UNUSED_PARAMETER!>a<!>: Int)
|
||||||
|
|
||||||
//Check multiple illegal modifiers in constructor
|
//Check multiple illegal modifiers in constructor
|
||||||
class IllegalModifiers2(<!WRONG_MODIFIER_TARGET!>private<!> <!WRONG_MODIFIER_TARGET!>abstract<!> <!UNUSED_PARAMETER!>a<!>: Int)
|
class IllegalModifiers2(<!WRONG_MODIFIER_TARGET!>private<!> <!INCOMPATIBLE_MODIFIERS!>abstract<!> <!UNUSED_PARAMETER!>a<!>: Int)
|
||||||
|
|
||||||
|
|
||||||
//Check annotations with illegal modifiers in constructor
|
//Check annotations with illegal modifiers in constructor
|
||||||
@@ -131,7 +131,7 @@ class IllegalModifiers8 {
|
|||||||
<!INCOMPATIBLE_MODIFIERS!>const<!>
|
<!INCOMPATIBLE_MODIFIERS!>const<!>
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
constructor(<!WRONG_MODIFIER_TARGET!>private<!> <!WRONG_MODIFIER_TARGET!>enum<!> <!WRONG_MODIFIER_TARGET!>abstract<!> <!UNUSED_PARAMETER!>x<!>: Int) {}
|
constructor(<!WRONG_MODIFIER_TARGET!>private<!> <!WRONG_MODIFIER_TARGET!>enum<!> <!INCOMPATIBLE_MODIFIERS!>abstract<!> <!UNUSED_PARAMETER!>x<!>: Int) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
class IllegalModifiers9 {
|
class IllegalModifiers9 {
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ public abstract class TestBug1() {
|
|||||||
position(m1().second)
|
position(m1().second)
|
||||||
}
|
}
|
||||||
|
|
||||||
private abstract fun m1(): Pair<Int, Int>
|
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>abstract<!> fun m1(): Pair<Int, Int>
|
||||||
|
|
||||||
private fun position(<!UNUSED_PARAMETER!>p<!>: Int) {}
|
private fun position(<!UNUSED_PARAMETER!>p<!>: Int) {}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class C : A() {
|
|||||||
|
|
||||||
//------------
|
//------------
|
||||||
open class D {
|
open class D {
|
||||||
private open fun self() : D = this
|
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>open<!> fun self() : D = this
|
||||||
}
|
}
|
||||||
|
|
||||||
class E : D() {
|
class E : D() {
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
open class A<out T> {
|
|
||||||
private open fun foo(t: T) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
class B : A<String>() {
|
|
||||||
<caret>
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
open class A<out T> {
|
|
||||||
private open fun foo(t: T) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
class B : A<String>() {
|
|
||||||
override fun equals(other: Any?): Boolean {
|
|
||||||
<selection><caret>return super.equals(other)</selection>
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
|
||||||
return super.hashCode()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String {
|
|
||||||
return super.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -152,10 +152,6 @@ public class OverrideImplementTest : AbstractOverrideImplementTest() {
|
|||||||
doMultiOverrideDirectoryTest()
|
doMultiOverrideDirectoryTest()
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun testPrivateToThis() {
|
|
||||||
doMultiOverrideFileTest()
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun testInheritVisibilities() {
|
public fun testInheritVisibilities() {
|
||||||
doMultiOverrideFileTest()
|
doMultiOverrideFileTest()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user