[FIR] Implement PACKAGE_OR_CLASSIFIER_REDECLARATION
Fix REDECLARATION positioning
This commit is contained in:
+13
-13
@@ -8,17 +8,17 @@ fun test() {}
|
||||
|
||||
fun test(z: Int, c: Char) {}
|
||||
|
||||
<!REDECLARATION!>open class A {
|
||||
open class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> {
|
||||
open fun rest(s: String) {}
|
||||
|
||||
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!>fun rest(s: String)<!> {}
|
||||
@@ -26,17 +26,17 @@ fun test(z: Int, c: Char) {}
|
||||
fun rest(l: Long) {}
|
||||
|
||||
<!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<!>
|
||||
<!REDECLARATION!>val u = 20<!>
|
||||
val <!REDECLARATION!>u<!> = 10
|
||||
val <!REDECLARATION!>u<!> = 20
|
||||
|
||||
<!REDECLARATION!>typealias TA = A<!>
|
||||
<!REDECLARATION!>typealias TA = B<!>
|
||||
typealias <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>TA<!> = A
|
||||
typealias <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>TA<!> = B
|
||||
|
||||
typealias BA = A
|
||||
|
||||
@@ -52,7 +52,7 @@ fun lol(a: Array<Boolean>) {}
|
||||
|
||||
class M {
|
||||
companion <!REDECLARATION!>object<!> {}
|
||||
<!REDECLARATION!>val Companion = object : Any {}<!>
|
||||
val <!REDECLARATION!>Companion<!> = object : Any {}
|
||||
}
|
||||
|
||||
fun B.foo() {}
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
|
||||
sealed class A
|
||||
|
||||
<!REDECLARATION!>class B : A()<!>
|
||||
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> : A()
|
||||
|
||||
interface C : <!INTERFACE_WITH_SUPERCLASS!>A<!>
|
||||
|
||||
@@ -30,7 +30,7 @@ sealed class P {
|
||||
|
||||
class K : P()
|
||||
|
||||
<!REDECLARATION!>object B<!> {
|
||||
object <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> {
|
||||
class I : P()
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
<!REDECLARATION!>object A<!>
|
||||
object <!REDECLARATION!>A<!>
|
||||
|
||||
<!REDECLARATION!>val A = 10<!>
|
||||
val <!REDECLARATION!>A<!> = 10
|
||||
|
||||
|
||||
fun foo() = A
|
||||
|
||||
compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantSetterParameterTypeChecker.kt
Vendored
+5
-5
@@ -2,15 +2,15 @@
|
||||
@Target(AnnotationTarget.VALUE_PARAMETER)
|
||||
annotation class Ann
|
||||
|
||||
<!REDECLARATION!>var x: Int
|
||||
var <!REDECLARATION!>x<!>: Int
|
||||
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<!>) {
|
||||
field = "$param "
|
||||
}<!>
|
||||
}
|
||||
|
||||
class My {
|
||||
var y: Int = 1
|
||||
@@ -25,4 +25,4 @@ class My {
|
||||
set(param) {
|
||||
field = !param
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+4
-4
@@ -10,11 +10,11 @@ internal <!NOTHING_TO_INLINE!>inline<!> fun internal() {
|
||||
f()
|
||||
}
|
||||
|
||||
<!REDECLARATION!>class C {
|
||||
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>C<!> {
|
||||
internal val z = object {
|
||||
fun foo() = 13
|
||||
}
|
||||
}<!>
|
||||
}
|
||||
|
||||
class Foo2<
|
||||
T1,
|
||||
@@ -26,12 +26,12 @@ class Foo2<
|
||||
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<!> fun bar() {}
|
||||
|
||||
}<!>
|
||||
}
|
||||
|
||||
open class D {
|
||||
protected open fun willRemainProtected() {
|
||||
|
||||
@@ -13,7 +13,7 @@ fun test() {
|
||||
val Any.bar get() = "456"
|
||||
val String.bar get() = "987"
|
||||
|
||||
<!REDECLARATION!>val t = "".bar<!>
|
||||
val <!REDECLARATION!>t<!> = "".bar
|
||||
|
||||
val p = Pair(0, "")
|
||||
|
||||
@@ -21,4 +21,4 @@ open class Base<T>(val x: T)
|
||||
class Derived : Base<Int>(10)
|
||||
val xx = Derived().x + 1
|
||||
|
||||
<!REDECLARATION!>val t = throw AssertionError("")<!>
|
||||
val <!REDECLARATION!>t<!> = throw AssertionError("")
|
||||
|
||||
+4
-1
@@ -714,7 +714,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
val CONFLICTING_OVERLOADS by error<PsiElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
||||
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")
|
||||
}
|
||||
val METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE by error<PsiElement>()
|
||||
|
||||
+2
-1
@@ -394,7 +394,8 @@ object FirErrors {
|
||||
// Redeclarations
|
||||
val MANY_COMPANION_OBJECTS by error0<KtObjectDeclaration>(SourceElementPositioningStrategies.COMPANION_OBJECT)
|
||||
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>()
|
||||
|
||||
// Invalid local declarations
|
||||
|
||||
+31
-9
@@ -5,15 +5,21 @@
|
||||
|
||||
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.analysis.checkers.FirDeclarationInspector
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationPresenter
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
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.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.getOuterClass
|
||||
import org.jetbrains.kotlin.fir.scopes.PACKAGE_MEMBER
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
|
||||
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.impl.FirCallableSymbol
|
||||
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.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames.UNDERSCORE_FOR_UNUSED_VAR
|
||||
import org.jetbrains.kotlin.utils.SmartSet
|
||||
|
||||
object FirConflictsChecker : FirBasicDeclarationChecker() {
|
||||
@@ -197,7 +207,8 @@ object FirConflictsChecker : FirBasicDeclarationChecker() {
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
if (declarationName != null) {
|
||||
session.lookupTracker?.recordLookup(
|
||||
@@ -216,14 +227,25 @@ object FirConflictsChecker : FirBasicDeclarationChecker() {
|
||||
else -> return
|
||||
}
|
||||
|
||||
inspector.declarationConflictingSymbols.forEach { (declaration, symbols) ->
|
||||
when {
|
||||
symbols.isEmpty() -> {}
|
||||
declaration is FirSimpleFunction || declaration is FirConstructor -> {
|
||||
reporter.reportOn(declaration.source, FirErrors.CONFLICTING_OVERLOADS, symbols, context)
|
||||
}
|
||||
else -> {
|
||||
reporter.reportOn(declaration.source, FirErrors.REDECLARATION, symbols, context)
|
||||
inspector.declarationConflictingSymbols.forEach { (conflictingDeclaration, symbols) ->
|
||||
val source = conflictingDeclaration.source
|
||||
if (source != null && symbols.isNotEmpty()) {
|
||||
when (conflictingDeclaration) {
|
||||
is FirSimpleFunction,
|
||||
is FirConstructor -> {
|
||||
reporter.reportOn(source, FirErrors.CONFLICTING_OVERLOADS, symbols, context)
|
||||
}
|
||||
else -> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-1
@@ -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() {
|
||||
override fun mark(
|
||||
node: LighterASTNode,
|
||||
@@ -725,7 +740,7 @@ object LightTreePositioningStrategies {
|
||||
if (node.tokenType == KtNodeTypes.LABEL_QUALIFIER) {
|
||||
return super.mark(node, startOffset, endOffset - 1, tree)
|
||||
}
|
||||
return super.mark(node, startOffset, endOffset, tree)
|
||||
return DEFAULT.mark(node, startOffset, endOffset, tree)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -278,8 +278,12 @@ object SourceElementPositioningStrategies {
|
||||
FirPsiPositioningStrategies.UNREACHABLE_CODE
|
||||
)
|
||||
|
||||
val ACTUAL_DECLARATION_NAME = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.ACTUAL_DECLARATION_NAME,
|
||||
PositioningStrategies.ACTUAL_DECLARATION_NAME
|
||||
)
|
||||
|
||||
// TODO
|
||||
val ACTUAL_DECLARATION_NAME = DEFAULT
|
||||
val INCOMPATIBLE_DECLARATION = DEFAULT
|
||||
|
||||
val NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT = SourceElementPositioningStrategy(
|
||||
|
||||
@@ -502,7 +502,7 @@ fun getOuterClassAndActualTypeParametersCount(klass: FirRegularClass, session: F
|
||||
return Pair(outerClass, result)
|
||||
}
|
||||
|
||||
fun getOuterClass(klass: FirRegularClass, session: FirSession): FirRegularClass? {
|
||||
fun getOuterClass(klass: FirClassLikeDeclaration, session: FirSession): FirRegularClass? {
|
||||
val classId = klass.symbol.classId
|
||||
val parentId = classId.relativeClassName.parent()
|
||||
if (!parentId.isRoot) {
|
||||
|
||||
Reference in New Issue
Block a user