FIR: consolidate duplicated logic in FirOverrideChecker
This commit is contained in:
committed by
Mikhail Glukhikh
parent
8bb98f8f86
commit
d3dfb33f89
+46
-72
@@ -19,9 +19,13 @@ import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
|||||||
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions
|
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions
|
||||||
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties
|
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.toConeType
|
import org.jetbrains.kotlin.fir.scopes.impl.toConeType
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.fir.typeContext
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
|
import org.jetbrains.kotlin.fir.types.upperBoundIfFlexible
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
@@ -36,23 +40,24 @@ object FirOverrideChecker : FirClassChecker() {
|
|||||||
val firTypeScope = declaration.unsubstitutedScope(context)
|
val firTypeScope = declaration.unsubstitutedScope(context)
|
||||||
|
|
||||||
for (it in declaration.declarations) {
|
for (it in declaration.declarations) {
|
||||||
when (it) {
|
if (it is FirSimpleFunction || it is FirProperty) {
|
||||||
is FirSimpleFunction -> checkFunction(it, reporter, typeCheckerContext, firTypeScope, context)
|
checkMember(it as FirCallableMemberDeclaration<*>, reporter, typeCheckerContext, firTypeScope, context)
|
||||||
is FirProperty -> checkProperty(it, reporter, typeCheckerContext, firTypeScope, context)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirTypeScope.retrieveDirectOverriddenOf(function: FirSimpleFunction): List<FirFunctionSymbol<*>> {
|
private fun FirTypeScope.retrieveDirectOverriddenOf(member: FirCallableMemberDeclaration<*>): List<FirCallableSymbol<*>> {
|
||||||
processFunctionsByName(function.name) {}
|
return when (member) {
|
||||||
|
is FirSimpleFunction -> {
|
||||||
return getDirectOverriddenFunctions(function.symbol)
|
processFunctionsByName(member.name) {}
|
||||||
}
|
getDirectOverriddenFunctions(member.symbol)
|
||||||
|
}
|
||||||
private fun FirTypeScope.retrieveDirectOverriddenOf(property: FirProperty): List<FirPropertySymbol> {
|
is FirProperty -> {
|
||||||
processPropertiesByName(property.name) {}
|
processPropertiesByName(member.name) {}
|
||||||
|
getDirectOverriddenProperties(member.symbol)
|
||||||
return getDirectOverriddenProperties(property.symbol)
|
}
|
||||||
|
else -> throw IllegalArgumentException("unexpected member kind $member")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeKotlinType.substituteAllTypeParameters(
|
private fun ConeKotlinType.substituteAllTypeParameters(
|
||||||
@@ -160,80 +165,49 @@ object FirOverrideChecker : FirClassChecker() {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkFunction(
|
private fun checkMember(
|
||||||
function: FirSimpleFunction,
|
member: FirCallableMemberDeclaration<*>,
|
||||||
reporter: DiagnosticReporter,
|
reporter: DiagnosticReporter,
|
||||||
typeCheckerContext: AbstractTypeCheckerContext,
|
typeCheckerContext: AbstractTypeCheckerContext,
|
||||||
firTypeScope: FirTypeScope,
|
firTypeScope: FirTypeScope,
|
||||||
context: CheckerContext,
|
context: CheckerContext,
|
||||||
) {
|
) {
|
||||||
if (!function.isOverride) {
|
if (!member.isOverride) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val overriddenFunctionSymbols = firTypeScope.retrieveDirectOverriddenOf(function)
|
val overriddenMemberSymbols = firTypeScope.retrieveDirectOverriddenOf(member)
|
||||||
|
|
||||||
if (overriddenFunctionSymbols.isEmpty()) {
|
if (overriddenMemberSymbols.isEmpty()) {
|
||||||
reporter.reportNothingToOverride(function, context)
|
reporter.reportNothingToOverride(member, context)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
checkModality(overriddenFunctionSymbols)?.let {
|
checkModality(overriddenMemberSymbols)?.let {
|
||||||
reporter.reportOverridingFinalMember(function, it, context)
|
reporter.reportOverridingFinalMember(member, it, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
function.checkVisibility(reporter, overriddenFunctionSymbols, context)
|
if (member is FirProperty) {
|
||||||
|
member.checkMutability(overriddenMemberSymbols)?.let {
|
||||||
|
reporter.reportVarOverriddenByVal(member, it, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val restriction = function.checkReturnType(
|
member.checkVisibility(reporter, overriddenMemberSymbols, context)
|
||||||
overriddenSymbols = overriddenFunctionSymbols,
|
|
||||||
|
val restriction = member.checkReturnType(
|
||||||
|
overriddenSymbols = overriddenMemberSymbols,
|
||||||
typeCheckerContext = typeCheckerContext,
|
typeCheckerContext = typeCheckerContext,
|
||||||
context = context,
|
context = context,
|
||||||
)
|
) ?: return
|
||||||
|
when (member) {
|
||||||
restriction?.let {
|
is FirSimpleFunction -> reporter.reportReturnTypeMismatchOnFunction(member, restriction, context)
|
||||||
reporter.reportReturnTypeMismatchOnFunction(function, it, context)
|
is FirProperty -> {
|
||||||
}
|
if (member.isVar) {
|
||||||
}
|
reporter.reportTypeMismatchOnVariable(member, restriction, context)
|
||||||
|
} else {
|
||||||
private fun checkProperty(
|
reporter.reportTypeMismatchOnProperty(member, restriction, context)
|
||||||
property: FirProperty,
|
}
|
||||||
reporter: DiagnosticReporter,
|
|
||||||
typeCheckerContext: AbstractTypeCheckerContext,
|
|
||||||
firTypeScope: FirTypeScope,
|
|
||||||
context: CheckerContext,
|
|
||||||
) {
|
|
||||||
if (!property.isOverride) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val overriddenPropertySymbols = firTypeScope.retrieveDirectOverriddenOf(property)
|
|
||||||
|
|
||||||
if (overriddenPropertySymbols.isEmpty()) {
|
|
||||||
reporter.reportNothingToOverride(property, context)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
checkModality(overriddenPropertySymbols)?.let {
|
|
||||||
reporter.reportOverridingFinalMember(property, it, context)
|
|
||||||
}
|
|
||||||
|
|
||||||
property.checkMutability(overriddenPropertySymbols)?.let {
|
|
||||||
reporter.reportVarOverriddenByVal(property, it, context)
|
|
||||||
}
|
|
||||||
|
|
||||||
property.checkVisibility(reporter, overriddenPropertySymbols, context)
|
|
||||||
|
|
||||||
val restriction = property.checkReturnType(
|
|
||||||
overriddenSymbols = overriddenPropertySymbols,
|
|
||||||
typeCheckerContext = typeCheckerContext,
|
|
||||||
context = context,
|
|
||||||
)
|
|
||||||
|
|
||||||
restriction?.let {
|
|
||||||
if (property.isVar) {
|
|
||||||
reporter.reportTypeMismatchOnVariable(property, it, context)
|
|
||||||
} else {
|
|
||||||
reporter.reportTypeMismatchOnProperty(property, it, context)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -3,5 +3,8 @@
|
|||||||
Compiling files:
|
Compiling files:
|
||||||
src/Sub.kt
|
src/Sub.kt
|
||||||
End of files
|
End of files
|
||||||
Exit code: OK
|
Exit code: ABORT
|
||||||
|
------------------------------------------
|
||||||
|
COMPILATION FAILED
|
||||||
|
'y' hides member of supertype 'Super' and needs 'override' modifier
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user