[FIR] Implement PACKAGE_OR_CLASSIFIER_REDECLARATION

Fix REDECLARATION positioning
This commit is contained in:
Ivan Kochurkin
2021-07-23 23:49:43 +03:00
committed by Space
parent 1c678be0d3
commit fd92b851a2
60 changed files with 166 additions and 262 deletions
@@ -8,17 +8,17 @@ fun test() {}
fun test(z: Int, c: Char) {} fun test(z: Int, c: Char) {}
<!REDECLARATION!>open class A { open class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> {
open fun rest(s: String) {} open fun rest(s: String) {}
open val u = 20 open val u = 20
}<!> }
<!REDECLARATION!>class A { class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> {
}<!> }
<!REDECLARATION!>class B : <!FINAL_SUPERTYPE, SUPERTYPE_NOT_INITIALIZED!>A<!> { class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> : <!FINAL_SUPERTYPE, SUPERTYPE_NOT_INITIALIZED!>A<!> {
<!CONFLICTING_OVERLOADS!><!NOTHING_TO_OVERRIDE!>override<!> fun rest(s: String)<!> {} <!CONFLICTING_OVERLOADS!><!NOTHING_TO_OVERRIDE!>override<!> fun rest(s: String)<!> {}
<!CONFLICTING_OVERLOADS!>fun rest(s: String)<!> {} <!CONFLICTING_OVERLOADS!>fun rest(s: String)<!> {}
@@ -26,17 +26,17 @@ fun test(z: Int, c: Char) {}
fun rest(l: Long) {} fun rest(l: Long) {}
<!NOTHING_TO_OVERRIDE!>override<!> val u = 310 <!NOTHING_TO_OVERRIDE!>override<!> val u = 310
}<!> }
<!REDECLARATION!>interface B<!> interface <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!>
<!REDECLARATION!>enum class B<!> enum class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!>
<!REDECLARATION!>val u = 10<!> val <!REDECLARATION!>u<!> = 10
<!REDECLARATION!>val u = 20<!> val <!REDECLARATION!>u<!> = 20
<!REDECLARATION!>typealias TA = A<!> typealias <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>TA<!> = A
<!REDECLARATION!>typealias TA = B<!> typealias <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>TA<!> = B
typealias BA = A typealias BA = A
@@ -52,7 +52,7 @@ fun lol(a: Array<Boolean>) {}
class M { class M {
companion <!REDECLARATION!>object<!> {} companion <!REDECLARATION!>object<!> {}
<!REDECLARATION!>val Companion = object : Any {}<!> val <!REDECLARATION!>Companion<!> = object : Any {}
} }
fun B.foo() {} fun B.foo() {}
@@ -2,7 +2,7 @@
sealed class A sealed class A
<!REDECLARATION!>class B : A()<!> class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> : A()
interface C : <!INTERFACE_WITH_SUPERCLASS!>A<!> interface C : <!INTERFACE_WITH_SUPERCLASS!>A<!>
@@ -30,7 +30,7 @@ sealed class P {
class K : P() class K : P()
<!REDECLARATION!>object B<!> { object <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> {
class I : P() class I : P()
} }
@@ -1,6 +1,6 @@
<!REDECLARATION!>object A<!> object <!REDECLARATION!>A<!>
<!REDECLARATION!>val A = 10<!> val <!REDECLARATION!>A<!> = 10
fun foo() = A fun foo() = A
@@ -2,15 +2,15 @@
@Target(AnnotationTarget.VALUE_PARAMETER) @Target(AnnotationTarget.VALUE_PARAMETER)
annotation class Ann annotation class Ann
<!REDECLARATION!>var x: Int var <!REDECLARATION!>x<!>: Int
get() = 1 get() = 1
set(@Ann private x) { }<!> set(@Ann private x) { }
<!REDECLARATION!>var x: String = "" var <!REDECLARATION!>x<!>: String = ""
set(param: <!REDUNDANT_SETTER_PARAMETER_TYPE!>String<!>) { set(param: <!REDUNDANT_SETTER_PARAMETER_TYPE!>String<!>) {
field = "$param " field = "$param "
}<!> }
class My { class My {
var y: Int = 1 var y: Int = 1
@@ -10,11 +10,11 @@ internal <!NOTHING_TO_INLINE!>inline<!> fun internal() {
f() f()
} }
<!REDECLARATION!>class C { class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>C<!> {
internal val z = object { internal val z = object {
fun foo() = 13 fun foo() = 13
} }
}<!> }
class Foo2< class Foo2<
T1, T1,
@@ -26,12 +26,12 @@ class Foo2<
internal inner class B<T,T2,> internal inner class B<T,T2,>
} }
<!REDECLARATION!><!REDUNDANT_VISIBILITY_MODIFIER!>public<!> class C { <!REDUNDANT_VISIBILITY_MODIFIER!>public<!> class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>C<!> {
<!REDUNDANT_VISIBILITY_MODIFIER!>public<!> val foo: Int = 0 <!REDUNDANT_VISIBILITY_MODIFIER!>public<!> val foo: Int = 0
<!REDUNDANT_VISIBILITY_MODIFIER!>public<!> fun bar() {} <!REDUNDANT_VISIBILITY_MODIFIER!>public<!> fun bar() {}
}<!> }
open class D { open class D {
protected open fun willRemainProtected() { protected open fun willRemainProtected() {
@@ -13,7 +13,7 @@ fun test() {
val Any.bar get() = "456" val Any.bar get() = "456"
val String.bar get() = "987" val String.bar get() = "987"
<!REDECLARATION!>val t = "".bar<!> val <!REDECLARATION!>t<!> = "".bar
val p = Pair(0, "") val p = Pair(0, "")
@@ -21,4 +21,4 @@ open class Base<T>(val x: T)
class Derived : Base<Int>(10) class Derived : Base<Int>(10)
val xx = Derived().x + 1 val xx = Derived().x + 1
<!REDECLARATION!>val t = throw AssertionError("")<!> val <!REDECLARATION!>t<!> = throw AssertionError("")
@@ -714,7 +714,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val CONFLICTING_OVERLOADS by error<PsiElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) { val CONFLICTING_OVERLOADS by error<PsiElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
parameter<Collection<Symbol>>("conflictingOverloads") parameter<Collection<Symbol>>("conflictingOverloads")
} }
val REDECLARATION by error<PsiElement> { val REDECLARATION by error<KtNamedDeclaration>(PositioningStrategy.NAME_IDENTIFIER) {
parameter<Collection<Symbol>>("conflictingDeclarations")
}
val PACKAGE_OR_CLASSIFIER_REDECLARATION by error<KtNamedDeclaration>(PositioningStrategy.ACTUAL_DECLARATION_NAME) {
parameter<Collection<Symbol>>("conflictingDeclarations") parameter<Collection<Symbol>>("conflictingDeclarations")
} }
val METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE by error<PsiElement>() val METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE by error<PsiElement>()
@@ -394,7 +394,8 @@ object FirErrors {
// Redeclarations // Redeclarations
val MANY_COMPANION_OBJECTS by error0<KtObjectDeclaration>(SourceElementPositioningStrategies.COMPANION_OBJECT) val MANY_COMPANION_OBJECTS by error0<KtObjectDeclaration>(SourceElementPositioningStrategies.COMPANION_OBJECT)
val CONFLICTING_OVERLOADS by error1<PsiElement, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT) val CONFLICTING_OVERLOADS by error1<PsiElement, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
val REDECLARATION by error1<PsiElement, Collection<FirBasedSymbol<*>>>() val REDECLARATION by error1<KtNamedDeclaration, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.NAME_IDENTIFIER)
val PACKAGE_OR_CLASSIFIER_REDECLARATION by error1<KtNamedDeclaration, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME)
val METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE by error0<PsiElement>() val METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE by error0<PsiElement>()
// Invalid local declarations // Invalid local declarations
@@ -5,15 +5,21 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.diagnostics.PositioningStrategies
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationInspector import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationInspector
import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationPresenter import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationPresenter
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.SourceElementPositioningStrategies
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
import org.jetbrains.kotlin.fir.declarations.utils.isInner
import org.jetbrains.kotlin.fir.resolve.firProvider import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.getOuterClass
import org.jetbrains.kotlin.fir.scopes.PACKAGE_MEMBER import org.jetbrains.kotlin.fir.scopes.PACKAGE_MEMBER
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
@@ -21,9 +27,13 @@ import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.ensureResolved import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.util.ListMultimap
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames.UNDERSCORE_FOR_UNUSED_VAR
import org.jetbrains.kotlin.utils.SmartSet import org.jetbrains.kotlin.utils.SmartSet
object FirConflictsChecker : FirBasicDeclarationChecker() { object FirConflictsChecker : FirBasicDeclarationChecker() {
@@ -197,7 +207,8 @@ object FirConflictsChecker : FirBasicDeclarationChecker() {
} }
} }
} }
else -> {} else -> {
}
} }
if (declarationName != null) { if (declarationName != null) {
session.lookupTracker?.recordLookup( session.lookupTracker?.recordLookup(
@@ -216,14 +227,25 @@ object FirConflictsChecker : FirBasicDeclarationChecker() {
else -> return else -> return
} }
inspector.declarationConflictingSymbols.forEach { (declaration, symbols) -> inspector.declarationConflictingSymbols.forEach { (conflictingDeclaration, symbols) ->
when { val source = conflictingDeclaration.source
symbols.isEmpty() -> {} if (source != null && symbols.isNotEmpty()) {
declaration is FirSimpleFunction || declaration is FirConstructor -> { when (conflictingDeclaration) {
reporter.reportOn(declaration.source, FirErrors.CONFLICTING_OVERLOADS, symbols, context) is FirSimpleFunction,
is FirConstructor -> {
reporter.reportOn(source, FirErrors.CONFLICTING_OVERLOADS, symbols, context)
} }
else -> { else -> {
reporter.reportOn(declaration.source, FirErrors.REDECLARATION, symbols, context) val factory = if (conflictingDeclaration is FirClassLikeDeclaration &&
getOuterClass(conflictingDeclaration, context.session) == null &&
symbols.any { it is FirClassLikeSymbol<*> }
) {
FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION
} else {
FirErrors.REDECLARATION
}
reporter.reportOn(source, factory, symbols, context)
}
} }
} }
} }
@@ -187,6 +187,21 @@ object LightTreePositioningStrategies {
} }
} }
val ACTUAL_DECLARATION_NAME: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(
node: LighterASTNode,
startOffset: Int,
endOffset: Int,
tree: FlyweightCapableTreeStructure<LighterASTNode>
): List<TextRange> {
val nameIdentifier = tree.nameIdentifier(node)
if (nameIdentifier != null) {
return markElement(nameIdentifier, startOffset, endOffset, tree, node)
}
return DEFAULT.mark(node, startOffset, endOffset, tree)
}
}
val DECLARATION_SIGNATURE: LightTreePositioningStrategy = object : LightTreePositioningStrategy() { val DECLARATION_SIGNATURE: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark( override fun mark(
node: LighterASTNode, node: LighterASTNode,
@@ -725,7 +740,7 @@ object LightTreePositioningStrategies {
if (node.tokenType == KtNodeTypes.LABEL_QUALIFIER) { if (node.tokenType == KtNodeTypes.LABEL_QUALIFIER) {
return super.mark(node, startOffset, endOffset - 1, tree) return super.mark(node, startOffset, endOffset - 1, tree)
} }
return super.mark(node, startOffset, endOffset, tree) return DEFAULT.mark(node, startOffset, endOffset, tree)
} }
} }
@@ -278,8 +278,12 @@ object SourceElementPositioningStrategies {
FirPsiPositioningStrategies.UNREACHABLE_CODE FirPsiPositioningStrategies.UNREACHABLE_CODE
) )
val ACTUAL_DECLARATION_NAME = SourceElementPositioningStrategy(
LightTreePositioningStrategies.ACTUAL_DECLARATION_NAME,
PositioningStrategies.ACTUAL_DECLARATION_NAME
)
// TODO // TODO
val ACTUAL_DECLARATION_NAME = DEFAULT
val INCOMPATIBLE_DECLARATION = DEFAULT val INCOMPATIBLE_DECLARATION = DEFAULT
val NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT = SourceElementPositioningStrategy( val NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT = SourceElementPositioningStrategy(
@@ -502,7 +502,7 @@ fun getOuterClassAndActualTypeParametersCount(klass: FirRegularClass, session: F
return Pair(outerClass, result) return Pair(outerClass, result)
} }
fun getOuterClass(klass: FirRegularClass, session: FirSession): FirRegularClass? { fun getOuterClass(klass: FirClassLikeDeclaration, session: FirSession): FirRegularClass? {
val classId = klass.symbol.classId val classId = klass.symbol.classId
val parentId = classId.relativeClassName.parent() val parentId = classId.relativeClassName.parent()
if (!parentId.isRoot) { if (!parentId.isRoot) {
@@ -11,7 +11,7 @@ compiler or generated code. Use it at your own risk!
warning: ATTENTION! warning: ATTENTION!
This build uses in-dev FIR: This build uses in-dev FIR:
-Xuse-fir -Xuse-fir
compiler/testData/cli/jvm/firMultiplatformCompilationWithError/jvm.kt:1:1: error: actual class 'A' has no corresponding members for expected class members: compiler/testData/cli/jvm/firMultiplatformCompilationWithError/jvm.kt:1:18: error: actual class 'A' has no corresponding members for expected class members:
/A.foo /A.foo
@@ -1,20 +0,0 @@
// !DIAGNOSTICS: -DUPLICATE_CLASS_NAMES
package test
class A {
<!REDECLARATION!>object Companion<!>
companion <!REDECLARATION!>object<!>
}
class B {
companion <!REDECLARATION!>object Named<!>
<!REDECLARATION!>object Named<!>
}
class C {
<!REDECLARATION!>class Named<!>
companion <!REDECLARATION!>object Named<!>
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -DUPLICATE_CLASS_NAMES // !DIAGNOSTICS: -DUPLICATE_CLASS_NAMES
package test package test
@@ -1,9 +1,9 @@
data class A1(<!REDECLARATION!>val x: Int<!>, val y: String, <!REDECLARATION!>val x: Int<!>) { data class A1(val <!REDECLARATION!>x<!>: Int, val y: String, val <!REDECLARATION!>x<!>: Int) {
val z = "" val z = ""
} }
data class A2(<!REDECLARATION!>val x: Int<!>, val y: String) { data class A2(val <!REDECLARATION!>x<!>: Int, val y: String) {
<!REDECLARATION!>val x = ""<!> val <!REDECLARATION!>x<!> = ""
} }
data class A3(<!REDECLARATION!>val<!SYNTAX!><!> :Int<!>, <!REDECLARATION!>val<!SYNTAX!><!> : Int<!>) data class A3(<!REDECLARATION!>val<!SYNTAX!><!> :Int<!>, <!REDECLARATION!>val<!SYNTAX!><!> : Int<!>)
@@ -1,5 +0,0 @@
class C {
companion <!REDECLARATION!>object<!> {}
<!REDECLARATION!>val Companion = C<!>
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class C { class C {
companion <!REDECLARATION!>object<!> {} companion <!REDECLARATION!>object<!> {}
@@ -1,8 +1,8 @@
class B { class B {
companion <!REDECLARATION!>object A<!> { companion object <!REDECLARATION!>A<!> {
} }
<!REDECLARATION!>val A = this<!> val <!REDECLARATION!>A<!> = this
} }
class C { class C {
@@ -45,4 +45,4 @@ actual annotation class Foo5
actual annotation class Foo6(val s: String = "value") actual annotation class Foo6(val s: String = "value")
<!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>actual typealias Foo7 = Bar2<!> actual typealias <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>Foo7<!> = Bar2
@@ -34,9 +34,9 @@ actual class Foo1(val s: String)
actual class Foo2(val p: String = "value", i: Int) actual class Foo2(val p: String = "value", i: Int)
actual typealias Foo3 = JavaFoo actual typealias Foo3 = JavaFoo
<!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>actual class Bar1(val s: String)<!> actual class <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>Bar1<!>(val s: String)
<!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>actual class Bar2(val p: String = "value", i: Int)<!> actual class <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>Bar2<!>(val p: String = "value", i: Int)
<!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>actual typealias Bar3 = JavaBar<!> actual typealias <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>Bar3<!> = JavaBar
actual class Bar4(val s: String) { actual class Bar4(val s: String) {
constructor() : this("") constructor() : this("")
} }
@@ -23,6 +23,6 @@ interface Foo1
fun foo2(): Int = 0 fun foo2(): Int = 0
<!ACTUAL_WITHOUT_EXPECT, REDECLARATION!>actual class Foo3<!> <!ACTUAL_WITHOUT_EXPECT!>actual class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>Foo3<!><!>
<!REDECLARATION!>class Foo3<!> class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>Foo3<!>
@@ -39,7 +39,7 @@ actual class C {
actual inner class I actual inner class I
} }
<!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>actual class D<!> actual class <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>D<!>
actual class E { actual class E {
class N class N
@@ -18,7 +18,7 @@ expect class Foo {
// TODO: do not suppress UNSUPPORTED once JS files in multi-platform tests are analyzed with JS analyzer facade // TODO: do not suppress UNSUPPORTED once JS files in multi-platform tests are analyzed with JS analyzer facade
<!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>actual class Foo { actual class <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>Foo<!> {
<!ACTUAL_WITHOUT_EXPECT!>actual constructor(p: dynamic) {}<!> <!ACTUAL_WITHOUT_EXPECT!>actual constructor(p: dynamic) {}<!>
<!ACTUAL_WITHOUT_EXPECT!>actual fun f1(s: dynamic): dynamic = null!!<!> <!ACTUAL_WITHOUT_EXPECT!>actual fun f1(s: dynamic): dynamic = null!!<!>
@@ -26,4 +26,4 @@ expect class Foo {
<!ACTUAL_WITHOUT_EXPECT!>actual fun f2(s: dynamic): MutableMap<Boolean?, Foo> = null!!<!> <!ACTUAL_WITHOUT_EXPECT!>actual fun f2(s: dynamic): MutableMap<Boolean?, Foo> = null!!<!>
<!ACTUAL_WITHOUT_EXPECT!>actual fun <T : Set<Number>> f3(t: T): dynamic = null!!<!> <!ACTUAL_WITHOUT_EXPECT!>actual fun <T : Set<Number>> f3(t: T): dynamic = null!!<!>
}<!> }
@@ -20,7 +20,7 @@ expect inline class NonInlineActual(val x: Int)
actual inline class Foo1(val x: Int) { actual inline class Foo1(val x: Int) {
actual fun bar(): String = "Hello" actual fun bar(): String = "Hello"
} }
<!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>actual inline class Foo2(val x: String)<!> actual inline class <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>Foo2<!>(val x: String)
actual <!ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_INLINE_CLASS!>inline<!> class Foo3 actual <!ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_INLINE_CLASS!>inline<!> class Foo3
<!ACTUAL_WITHOUT_EXPECT!>actual inline class NonInlineExpect(val x: Int)<!> <!ACTUAL_WITHOUT_EXPECT!>actual inline class NonInlineExpect(val x: Int)<!>
@@ -1,4 +0,0 @@
class Aaa() {
<!REDECLARATION!>val a = 1<!>
<!REDECLARATION!>val a = 1<!>
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class Aaa() { class Aaa() {
val <!REDECLARATION!>a<!> = 1 val <!REDECLARATION!>a<!> = 1
val <!REDECLARATION!>a<!> = 1 val <!REDECLARATION!>a<!> = 1
@@ -1,4 +0,0 @@
class Aaa() {
<!REDECLARATION!>val a = 1<!>
<!REDECLARATION!>val a = ""<!>
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class Aaa() { class Aaa() {
val <!REDECLARATION!>a<!> = 1 val <!REDECLARATION!>a<!> = 1
val <!REDECLARATION!>a<!> = "" val <!REDECLARATION!>a<!> = ""
@@ -1,12 +0,0 @@
// FIR_IDE_IGNORE
// FILE: f1.kt
package test
<!REDECLARATION!>class A<!>
class F1
// FILE: f2.kt
package test
<!REDECLARATION!>class A<!>
class F2
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FIR_IDE_IGNORE // FIR_IDE_IGNORE
// FILE: f1.kt // FILE: f1.kt
package test package test
@@ -1,4 +0,0 @@
package foo
<!REDECLARATION!>val Int.foo: Int get() = 2<!>
<!REDECLARATION!>val Int.foo: Int get() = 3<!>
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
package foo package foo
val Int.<!REDECLARATION!>foo<!>: Int get() = 2 val Int.<!REDECLARATION!>foo<!>: Int get() = 2
@@ -1,13 +0,0 @@
public class A() {
<!REDECLARATION!>public val FOO: String = "test"<!>
<!REDECLARATION!>public class FOO() { }<!>
}
public class B() {
companion object {
<!REDECLARATION!>public val FOO: String = "test"<!>
<!REDECLARATION!>public class FOO() { }<!>
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
public class A() { public class A() {
public val <!REDECLARATION!>FOO<!>: String = "test" public val <!REDECLARATION!>FOO<!>: String = "test"
@@ -1,6 +0,0 @@
class A {
companion object B {
<!REDECLARATION!>class G<!>
<!REDECLARATION!>val G = 1<!>
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class A { class A {
companion object B { companion object B {
class <!REDECLARATION!>G<!> class <!REDECLARATION!>G<!>
@@ -1,9 +0,0 @@
// FILE: a.kt
<!REDECLARATION!>val a : Int = 1<!>
<!CONFLICTING_OVERLOADS!>fun f()<!> {
}
// FILE: b.kt
<!REDECLARATION!>val a : Int = 1<!>
<!CONFLICTING_OVERLOADS!>fun f()<!> {
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FILE: a.kt // FILE: a.kt
val <!REDECLARATION!>a<!> : Int = 1 val <!REDECLARATION!>a<!> : Int = 1
<!CONFLICTING_OVERLOADS!>fun f()<!> { <!CONFLICTING_OVERLOADS!>fun f()<!> {
@@ -1,14 +1,14 @@
// FILE: a.kt // FILE: a.kt
package redeclarations package redeclarations
<!REDECLARATION!>object A<!> { object <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> {
val x : Int = 0 val x : Int = 0
val A = 1 val A = 1
} }
<!REDECLARATION!>class A {}<!> class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> {}
<!REDECLARATION!>val A = 1<!> val <!REDECLARATION!>A<!> = 1
// FILE: b.kt // FILE: b.kt
package redeclarations.A package redeclarations.A
@@ -1,9 +0,0 @@
// !DIAGNOSTICS: -DUPLICATE_CLASS_NAMES
// KT-3525
object B {
<!REDECLARATION!>class C<!>
<!REDECLARATION!>class C<!>
<!REDECLARATION!>val a : Int = 1<!>
<!REDECLARATION!>val a : Int = 1<!>
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -DUPLICATE_CLASS_NAMES // !DIAGNOSTICS: -DUPLICATE_CLASS_NAMES
// KT-3525 // KT-3525
object B { object B {
@@ -8,7 +8,7 @@ private fun validFun() {}
private val validVal = 1 private val validVal = 1
<!CONFLICTING_OVERLOADS!>private fun invalidFun0()<!> {} <!CONFLICTING_OVERLOADS!>private fun invalidFun0()<!> {}
<!REDECLARATION!>private val invalidProp0 = 1<!> private val <!REDECLARATION!>invalidProp0<!> = 1
// NB invalidFun0 and invalidProp0 are conflicting overloads, since the following is an ambiguity: // NB invalidFun0 and invalidProp0 are conflicting overloads, since the following is an ambiguity:
fun useInvalidFun0() = invalidFun0() fun useInvalidFun0() = invalidFun0()
@@ -36,7 +36,7 @@ private val validVal = 1
<!CONFLICTING_OVERLOADS!>private fun invalidFun0()<!> {} <!CONFLICTING_OVERLOADS!>private fun invalidFun0()<!> {}
<!REDECLARATION!>private val invalidProp0 = 1<!> private val <!REDECLARATION!>invalidProp0<!> = 1
<!CONFLICTING_OVERLOADS!>internal fun invalidFun3()<!> {} <!CONFLICTING_OVERLOADS!>internal fun invalidFun3()<!> {}
<!CONFLICTING_OVERLOADS!>internal fun invalidFun4()<!> {} <!CONFLICTING_OVERLOADS!>internal fun invalidFun4()<!> {}
@@ -1,13 +1,13 @@
<!REDECLARATION!>val Test1 = null<!> val <!REDECLARATION!>Test1<!> = null
<!REDECLARATION!>class Test1<!> class <!REDECLARATION!>Test1<!>
<!REDECLARATION!>val Test2 = null<!> val <!REDECLARATION!>Test2<!> = null
<!REDECLARATION!>interface Test2<!> interface <!REDECLARATION!>Test2<!>
<!REDECLARATION!>val Test3 = null<!> val <!REDECLARATION!>Test3<!> = null
<!REDECLARATION!>object Test3<!> object <!REDECLARATION!>Test3<!>
<!REDECLARATION!>val Test4 = null<!> val <!REDECLARATION!>Test4<!> = null
<!REDECLARATION!>class Test4<!> class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>Test4<!>
<!REDECLARATION!>interface Test4<!> interface <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>Test4<!>
<!REDECLARATION!>object Test4<!> object <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>Test4<!>
@@ -1,18 +0,0 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -TOPLEVEL_TYPEALIASES_ONLY
// FILE: file1.kt
<!REDECLARATION!>class SomeClass<!>
<!REDECLARATION!>typealias SomeClass = Any<!>
<!REDECLARATION!>typealias SomeClass = Any<!>
<!REDECLARATION!>typealias SomeClass = Any<!>
class Outer {
<!REDECLARATION!>class Nested<!>
<!REDECLARATION!>typealias Nested = Any<!>
<!REDECLARATION!>typealias Nested = Any<!>
<!REDECLARATION!>typealias Nested = Any<!>
}
// FILE: file2.kt
<!REDECLARATION!>typealias SomeClass = Any<!>
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -TOPLEVEL_TYPEALIASES_ONLY // !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -TOPLEVEL_TYPEALIASES_ONLY
// FILE: file1.kt // FILE: file1.kt
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>SomeClass<!> class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>SomeClass<!>
@@ -1,13 +1,13 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -TOPLEVEL_TYPEALIASES_ONLY // !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -TOPLEVEL_TYPEALIASES_ONLY
// FILE: file1.kt // FILE: file1.kt
<!REDECLARATION!>typealias Test = String<!> typealias <!REDECLARATION!>Test<!> = String
<!REDECLARATION!>val Test = 42<!> val <!REDECLARATION!>Test<!> = 42
class Outer { class Outer {
<!REDECLARATION!>typealias Test = String<!> typealias <!REDECLARATION!>Test<!> = String
<!REDECLARATION!>val Test = 42<!> val <!REDECLARATION!>Test<!> = 42
} }
typealias Test2 = String typealias Test2 = String
@@ -1,22 +0,0 @@
// !DIAGNOSTICS: -DUPLICATE_CLASS_NAMES
//KT-2438 Prohibit inner classes with the same name
package kt2438
class B {
<!REDECLARATION!>class C<!>
<!REDECLARATION!>class C<!>
}
class A {
<!REDECLARATION!>class B<!>
companion object {
<!REDECLARATION!>class B<!>
<!REDECLARATION!>class B<!>
}
<!REDECLARATION!>class B<!>
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -DUPLICATE_CLASS_NAMES // !DIAGNOSTICS: -DUPLICATE_CLASS_NAMES
//KT-2438 Prohibit inner classes with the same name //KT-2438 Prohibit inner classes with the same name
@@ -1,37 +0,0 @@
<!REDECLARATION!>val a : Int = 1<!>
<!REDECLARATION!>val a : Int = 1<!>
<!REDECLARATION!>val a : Int = 1<!>
<!REDECLARATION!>val b : Int = 1<!>
<!REDECLARATION!>val b : Int = 1<!>
<!REDECLARATION!>val b : Int = 1<!>
<!REDECLARATION!>val b : Int = 1<!>
<!CONFLICTING_OVERLOADS!>fun foo()<!> {} // and here too
<!CONFLICTING_OVERLOADS!>fun foo()<!> {} // and here
<!CONFLICTING_OVERLOADS!>fun foo()<!> {} // and here
<!CONFLICTING_OVERLOADS!>fun foo()<!> {} // and here
<!CONFLICTING_OVERLOADS!>fun bar()<!> {} // and here
<!CONFLICTING_OVERLOADS!>fun bar()<!> {} // and here
<!CONFLICTING_OVERLOADS!>fun bar()<!> {} // and here
class A {
<!REDECLARATION!>val a : Int = 1<!>
<!REDECLARATION!>val a : Int = 1<!>
<!REDECLARATION!>val a : Int = 1<!>
<!REDECLARATION!>val b : Int = 1<!>
<!REDECLARATION!>val b : Int = 1<!>
<!REDECLARATION!>val b : Int = 1<!>
<!REDECLARATION!>val b : Int = 1<!>
<!CONFLICTING_OVERLOADS!>fun foo()<!> {} // and here too
<!CONFLICTING_OVERLOADS!>fun foo()<!> {} // and here
<!CONFLICTING_OVERLOADS!>fun foo()<!> {} // and here
<!CONFLICTING_OVERLOADS!>fun foo()<!> {} // and here
<!CONFLICTING_OVERLOADS!>fun bar()<!> {} // and here
<!CONFLICTING_OVERLOADS!>fun bar()<!> {} // and here
<!CONFLICTING_OVERLOADS!>fun bar()<!> {} // and here
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
val <!REDECLARATION!>a<!> : Int = 1 val <!REDECLARATION!>a<!> : Int = 1
val <!REDECLARATION!>a<!> : Int = 1 val <!REDECLARATION!>a<!> : Int = 1
val <!REDECLARATION!>a<!> : Int = 1 val <!REDECLARATION!>a<!> : Int = 1
@@ -1,4 +0,0 @@
// JET-11 Redeclaration & Forward reference for classes cause an exception
<!REDECLARATION!>open class NoC<!>
class NoC1 : NoC()
<!REDECLARATION!>open class NoC<!>
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// JET-11 Redeclaration & Forward reference for classes cause an exception // JET-11 Redeclaration & Forward reference for classes cause an exception
open class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>NoC<!> open class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>NoC<!>
class NoC1 : NoC() class NoC1 : NoC()
@@ -1,11 +0,0 @@
<!REDECLARATION!>class A<!>
<!REDECLARATION!>class A {
constructor()
}<!>
class B
class Outer {
class B {
constructor()
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!>
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> { class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> {
constructor() constructor()
@@ -19,5 +19,5 @@ private val test1co: C.Companion = <!INITIALIZER_TYPE_MISMATCH, NO_COMPANION_OBJ
private val test2: TA = <!INITIALIZER_TYPE_MISMATCH!>TA(<!NO_VALUE_FOR_PARAMETER!>)<!><!> private val test2: TA = <!INITIALIZER_TYPE_MISMATCH!>TA(<!NO_VALUE_FOR_PARAMETER!>)<!><!>
private val test2co = TA private val test2co = TA
<!REDECLARATION!>private class C<!> private class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>C<!>
<!REDECLARATION!>private typealias TA = Int<!> private typealias <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>TA<!> = Int
@@ -54,9 +54,9 @@ class Case2() {
* TESTCASE NUMBER: 3 * TESTCASE NUMBER: 3
* NOTE: check abstract member cannot be accessed directly * NOTE: check abstract member cannot be accessed directly
*/ */
class Case3(<!REDECLARATION!>override val boo: String<!>) : BaseCase3() { class Case3(override val <!REDECLARATION!>boo<!>: String) : BaseCase3() {
override val zoo: String = super.<!ABSTRACT_SUPER_CALL!>foo<!>() override val zoo: String = super.<!ABSTRACT_SUPER_CALL!>foo<!>()
<!REDECLARATION!>override val boo: String = super.<!ABSTRACT_SUPER_CALL!>boo<!><!> override val <!REDECLARATION!>boo<!>: String = super.<!ABSTRACT_SUPER_CALL!>boo<!>
override val value: String = super.<!ABSTRACT_SUPER_CALL!>zoo<!> override val value: String = super.<!ABSTRACT_SUPER_CALL!>zoo<!>
val hoo: String = super.<!ABSTRACT_SUPER_CALL!>zoo<!> val hoo: String = super.<!ABSTRACT_SUPER_CALL!>zoo<!>
@@ -1929,6 +1929,15 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token, token,
) )
} }
add(FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION) { firDiagnostic ->
PackageOrClassifierRedeclarationImpl(
firDiagnostic.a.map { firBasedSymbol ->
firSymbolBuilder.buildSymbol(firBasedSymbol.fir)
},
firDiagnostic as FirPsiDiagnostic,
token,
)
}
add(FirErrors.METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE) { firDiagnostic -> add(FirErrors.METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE) { firDiagnostic ->
MethodOfAnyImplementedInInterfaceImpl( MethodOfAnyImplementedInInterfaceImpl(
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
@@ -1369,11 +1369,16 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract val conflictingOverloads: List<KtSymbol> abstract val conflictingOverloads: List<KtSymbol>
} }
abstract class Redeclaration : KtFirDiagnostic<PsiElement>() { abstract class Redeclaration : KtFirDiagnostic<KtNamedDeclaration>() {
override val diagnosticClass get() = Redeclaration::class override val diagnosticClass get() = Redeclaration::class
abstract val conflictingDeclarations: List<KtSymbol> abstract val conflictingDeclarations: List<KtSymbol>
} }
abstract class PackageOrClassifierRedeclaration : KtFirDiagnostic<KtNamedDeclaration>() {
override val diagnosticClass get() = PackageOrClassifierRedeclaration::class
abstract val conflictingDeclarations: List<KtSymbol>
}
abstract class MethodOfAnyImplementedInInterface : KtFirDiagnostic<PsiElement>() { abstract class MethodOfAnyImplementedInInterface : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = MethodOfAnyImplementedInInterface::class override val diagnosticClass get() = MethodOfAnyImplementedInInterface::class
} }
@@ -2187,7 +2187,15 @@ internal class RedeclarationImpl(
override val conflictingDeclarations: List<KtSymbol>, override val conflictingDeclarations: List<KtSymbol>,
firDiagnostic: FirPsiDiagnostic, firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken, override val token: ValidityToken,
) : KtFirDiagnostic.Redeclaration(), KtAbstractFirDiagnostic<PsiElement> { ) : KtFirDiagnostic.Redeclaration(), KtAbstractFirDiagnostic<KtNamedDeclaration> {
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
}
internal class PackageOrClassifierRedeclarationImpl(
override val conflictingDeclarations: List<KtSymbol>,
firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken,
) : KtFirDiagnostic.PackageOrClassifierRedeclaration(), KtAbstractFirDiagnostic<KtNamedDeclaration> {
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
} }