[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) {}
<!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,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()
}
@@ -1,6 +1,6 @@
<!REDECLARATION!>object A<!>
object <!REDECLARATION!>A<!>
<!REDECLARATION!>val A = 10<!>
val <!REDECLARATION!>A<!> = 10
fun foo() = A
@@ -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
}
}
}
@@ -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("")
@@ -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>()
@@ -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
@@ -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)
}
}
}
}
@@ -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)
}
}
@@ -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) {