[FIR] NOTHING_TO_OVERRIDE diagnostic
This commit is contained in:
committed by
teamcityserver
parent
9452b788bf
commit
b44785c24e
+2
-2
@@ -19,13 +19,13 @@ fun test(z: Int, c: Char) {}
|
||||
}<!>
|
||||
|
||||
<!REDECLARATION!>class B : <!FINAL_SUPERTYPE, SUPERTYPE_NOT_INITIALIZED!>A<!> {
|
||||
<!CONFLICTING_OVERLOADS!>override fun rest(s: String)<!> {}
|
||||
<!CONFLICTING_OVERLOADS!><!NOTHING_TO_OVERRIDE!>override<!> fun rest(s: String)<!> {}
|
||||
|
||||
<!CONFLICTING_OVERLOADS!>fun rest(s: String)<!> {}
|
||||
|
||||
fun rest(l: Long) {}
|
||||
|
||||
override val u = 310
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> val u = 310
|
||||
}<!>
|
||||
|
||||
<!REDECLARATION!>interface B<!>
|
||||
|
||||
Vendored
+3
-3
@@ -17,17 +17,17 @@ class CallBasedInExpressionGenerator(
|
||||
private val resolvedCall = operatorReference.<!UNRESOLVED_REFERENCE!>getResolvedCallWithAssert<!>(codegen.<!UNRESOLVED_REFERENCE!>bindingContext<!>)
|
||||
private val isInverted = operatorReference.<!UNRESOLVED_REFERENCE!>getReferencedNameElementType<!>() == <!UNRESOLVED_REFERENCE!>KtTokens<!>.NOT_IN
|
||||
|
||||
override fun generate(argument: StackValue): BranchedValue =
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun generate(argument: StackValue): BranchedValue =
|
||||
gen(argument).let { if (isInverted) <!UNRESOLVED_REFERENCE!>Invert<!>(it) else it }
|
||||
|
||||
private fun gen(argument: StackValue): BranchedValue =
|
||||
object : BranchedValue(<!TOO_MANY_ARGUMENTS!>argument<!>, <!TOO_MANY_ARGUMENTS!>null<!>, <!TOO_MANY_ARGUMENTS!>argument.<!UNRESOLVED_REFERENCE!>type<!><!>, <!TOO_MANY_ARGUMENTS!><!UNRESOLVED_REFERENCE!>Opcodes<!>.IFEQ<!>) {
|
||||
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||
invokeFunction(v)
|
||||
<!UNRESOLVED_REFERENCE!>coerceTo<!>(type, kotlinType, v)
|
||||
}
|
||||
|
||||
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
|
||||
invokeFunction(v)
|
||||
v.<!UNRESOLVED_REFERENCE!>visitJumpInsn<!>(if (jumpIfFalse) <!UNRESOLVED_REFERENCE!>Opcodes<!>.IFEQ else <!UNRESOLVED_REFERENCE!>Opcodes<!>.IFNE, jumpLabel)
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -25,7 +25,7 @@ interface B {
|
||||
interface Foo
|
||||
|
||||
expect abstract class AbstractClass : Foo {
|
||||
abstract override fun foo()
|
||||
abstract <!NOTHING_TO_OVERRIDE!>override<!> fun foo()
|
||||
|
||||
abstract fun bar()
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ open class A {
|
||||
class B : A() {
|
||||
override fun foo(): B = this
|
||||
fun <!VIRTUAL_MEMBER_HIDDEN!>bar<!>(): B = this // Missing 'override'
|
||||
override fun buz(p: B): B = this //No override as B not :> A
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun buz(p: B): B = this //No override as B not :> A
|
||||
|
||||
fun test() {
|
||||
foo()
|
||||
|
||||
+2
-2
@@ -6,8 +6,8 @@ public interface JA<E> {
|
||||
// FILE: main.kt
|
||||
|
||||
interface KB<F> {
|
||||
override fun getFoo(): F
|
||||
override fun getBar(): F
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun getFoo(): F
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun getBar(): F
|
||||
}
|
||||
|
||||
interface D1 : JA<String>, KB<String>
|
||||
|
||||
+1
-3
@@ -250,10 +250,8 @@ object FirOverrideChecker : FirClassChecker() {
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER") // TODO: delete me after implementing body
|
||||
private fun DiagnosticReporter.reportNothingToOverride(declaration: FirMemberDeclaration, context: CheckerContext) {
|
||||
// TODO: not ready yet, e.g., Collections
|
||||
// reportOn(declaration.source, FirErrors.NOTHING_TO_OVERRIDE, declaration, context)
|
||||
reportOn(declaration.source, FirErrors.NOTHING_TO_OVERRIDE, declaration, context)
|
||||
}
|
||||
|
||||
private fun DiagnosticReporter.reportOverridingFinalMember(
|
||||
|
||||
+11
-1
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isFinal
|
||||
import org.jetbrains.kotlin.fir.dispatchReceiverTypeOrNull
|
||||
import org.jetbrains.kotlin.fir.originalOrSelf
|
||||
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
|
||||
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions
|
||||
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
@@ -67,7 +68,16 @@ object FirJvmOverridesBackwardCompatibilityHelper : FirOverridesBackwardCompatib
|
||||
if (originalMember.origin !in javaOrigin) return false
|
||||
val containingClassName = originalMember.containingClass()?.classId?.asSingleFqName()?.toUnsafe() ?: return false
|
||||
// If the super class is mapped to a Kotlin built-in class, then we don't require `override` keyword.
|
||||
if (JavaToKotlinClassMap.mapKotlinToJava(containingClassName) != null) return true
|
||||
if (JavaToKotlinClassMap.mapKotlinToJava(containingClassName) != null) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (!originalMember.isAbstract) {
|
||||
val containingClass = originalMember.containingClass()?.toFirRegularClass(context.session)
|
||||
if (containingClass?.isInterface == false) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
val scope =
|
||||
symbol.dispatchReceiverTypeOrNull()?.toRegularClass(context.session)?.unsubstitutedScope(context) ?: return false
|
||||
|
||||
+10
@@ -58,9 +58,19 @@ class FirStandardOverrideChecker(private val session: FirSession) : FirAbstractO
|
||||
fun isEqualTypes(candidateTypeRef: FirTypeRef, baseTypeRef: FirTypeRef, substitutor: ConeSubstitutor): Boolean {
|
||||
candidateTypeRef.ensureResolvedTypeDeclaration(session, requiredPhase = FirResolvePhase.TYPES)
|
||||
baseTypeRef.ensureResolvedTypeDeclaration(session, requiredPhase = FirResolvePhase.TYPES)
|
||||
if (candidateTypeRef is FirErrorTypeRef && baseTypeRef is FirErrorTypeRef) {
|
||||
return maybeEqualErrorTypes(candidateTypeRef, baseTypeRef)
|
||||
}
|
||||
return isEqualTypes(candidateTypeRef.coneType, baseTypeRef.coneType, substitutor)
|
||||
}
|
||||
|
||||
private fun maybeEqualErrorTypes(ref1: FirErrorTypeRef, ref2: FirErrorTypeRef): Boolean {
|
||||
val delegated1 = ref1.delegatedTypeRef as? FirUserTypeRef ?: return false
|
||||
val delegated2 = ref2.delegatedTypeRef as? FirUserTypeRef ?: return false
|
||||
if (delegated1.qualifier.size != delegated2.qualifier.size) return false
|
||||
return delegated1.qualifier.zip(delegated2.qualifier).all { (l, r) -> l.name == r.name }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Good case complexity is O(1)
|
||||
|
||||
Reference in New Issue
Block a user