FIR: look for conflicting declarations more precisely

This commit is contained in:
Mikhail Glukhikh
2022-07-01 15:09:19 +02:00
committed by teamcity
parent 3092a84b6b
commit 4737bb07df
9 changed files with 29 additions and 56 deletions
@@ -61,9 +61,9 @@ class L {
fun B.foo() {}
}
fun mest() {}
<!CONFLICTING_OVERLOADS!>fun mest()<!> {}
class mest
class <!CONFLICTING_OVERLOADS!>mest<!>
<!FUNCTION_DECLARATION_WITH_NO_NAME!>fun()<!> {}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationInspector
import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationPresenter
@@ -95,13 +96,18 @@ object FirConflictsChecker : FirBasicDeclarationChecker() {
is FirCallableSymbol<*> -> session.firProvider.getFirCallableContainerFile(conflictingSymbol)
else -> null
}
if (containingFile == actualConflictingFile) return // TODO: rewrite local decls checker to the same logic and then remove the check
if (containingFile == actualConflictingFile && conflicting.origin == FirDeclarationOrigin.Precompiled) {
return // TODO: rewrite local decls checker to the same logic and then remove the check
}
if (areCompatibleMainFunctions(declaration, containingFile, conflicting, actualConflictingFile)) return
if (isExpectAndActual(declaration, conflicting)) return
if (
conflicting is FirMemberDeclaration &&
!session.visibilityChecker.isVisible(conflicting, session, containingFile, emptyList(), null)
) return
val declarationIsLowPriority = hasLowPriorityAnnotation(declaration.annotations)
val conflictingIsLowPriority = hasLowPriorityAnnotation(conflicting.annotations)
if (declarationIsLowPriority != conflictingIsLowPriority) return
declarationConflictingSymbols.getOrPut(declaration) { SmartSet.create() }.add(conflictingSymbol)
}
@@ -355,7 +361,7 @@ class FirNameConflictsTracker : FirNameConflictsTrackerComponent() {
}
}
private fun FirDeclaration.onConstructors(action: (ctor: FirConstructor) -> Unit) {
private fun FirRegularClass.onConstructors(action: (ctor: FirConstructor) -> Unit) {
class ClassConstructorVisitor : FirVisitorVoid() {
override fun visitElement(element: FirElement) {}
@@ -370,7 +376,9 @@ private fun FirDeclaration.onConstructors(action: (ctor: FirConstructor) -> Unit
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction) {}
}
acceptChildren(ClassConstructorVisitor())
if (classKind != ClassKind.OBJECT && classKind != ClassKind.ENUM_ENTRY) {
acceptChildren(ClassConstructorVisitor())
}
}
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
@@ -186,3 +187,11 @@ val FirAnnotation.resolved: Boolean
if (this !is FirAnnotationCall) return true
return calleeReference is FirResolvedNamedReference || calleeReference is FirErrorNamedReference
}
private val LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_CLASS_ID: ClassId =
ClassId(FqName("kotlin.internal"), Name.identifier("LowPriorityInOverloadResolution"))
fun hasLowPriorityAnnotation(annotations: List<FirAnnotation>) = annotations.any {
val lookupTag = it.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag ?: return@any false
lookupTag.classId == LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_CLASS_ID
}
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.FirVisibilityChecker
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isInfix
import org.jetbrains.kotlin.fir.declarations.utils.isOperator
@@ -33,8 +32,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.visibilityChecker
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.inference.isSubtypeConstraintCompatible
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
@@ -542,9 +539,6 @@ internal object CheckVisibility : CheckerStage() {
}
internal object CheckLowPriorityInOverloadResolution : CheckerStage() {
private val LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_CLASS_ID: ClassId =
ClassId(FqName("kotlin.internal"), Name.identifier("LowPriorityInOverloadResolution"))
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) {
val annotations = when (val fir = candidate.symbol.fir) {
is FirSimpleFunction -> fir.annotations
@@ -553,12 +547,7 @@ internal object CheckLowPriorityInOverloadResolution : CheckerStage() {
else -> return
}
val hasLowPriorityAnnotation = annotations.any {
val lookupTag = it.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag ?: return@any false
lookupTag.classId == LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_CLASS_ID
}
if (hasLowPriorityAnnotation) {
if (hasLowPriorityAnnotation(annotations)) {
sink.reportDiagnostic(ResolvedWithLowPriority)
}
}
@@ -2,9 +2,9 @@
package constructorVsFun
class a() { }
class a<!CONFLICTING_OVERLOADS!>()<!> { }
fun a() = 1
<!CONFLICTING_OVERLOADS!>fun a()<!> = 1
class Tram {
fun f() { }
@@ -10,7 +10,7 @@ object Foo {
fun En() = 239
enum class En {
enum class <!CONFLICTING_OVERLOADS!>En<!> {
ENTRY,
SUBCLASS { };
@@ -1,34 +0,0 @@
//If this test hangs, it means something is broken.
package c
fun z(view: () -> Unit) {}
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
<!CONFLICTING_OVERLOADS!>fun x()<!> = z { z { z { z { z { z { z { z { } } } } } } } }
class x() {}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
//If this test hangs, it means something is broken.
package c
@@ -7,10 +7,10 @@ class A(x: String = "", y: String = "") {
}
class B {
constructor(x: Int)
<!CONFLICTING_OVERLOADS!>constructor(x: Int)<!>
}
fun B(x: Int) {}
<!CONFLICTING_OVERLOADS!>fun B(x: Int)<!> {}
class Outer {
class A(x: String = "", y: String = "") {