FIR: consolidate duplicated logic in FirOverrideChecker

This commit is contained in:
Tianyu Geng
2021-05-24 14:29:25 -07:00
committed by Mikhail Glukhikh
parent 8bb98f8f86
commit d3dfb33f89
2 changed files with 50 additions and 73 deletions
@@ -19,9 +19,13 @@ import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenFunctions
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenProperties
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.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.AbstractTypeCheckerContext
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -36,23 +40,24 @@ object FirOverrideChecker : FirClassChecker() {
val firTypeScope = declaration.unsubstitutedScope(context)
for (it in declaration.declarations) {
when (it) {
is FirSimpleFunction -> checkFunction(it, reporter, typeCheckerContext, firTypeScope, context)
is FirProperty -> checkProperty(it, reporter, typeCheckerContext, firTypeScope, context)
if (it is FirSimpleFunction || it is FirProperty) {
checkMember(it as FirCallableMemberDeclaration<*>, reporter, typeCheckerContext, firTypeScope, context)
}
}
}
private fun FirTypeScope.retrieveDirectOverriddenOf(function: FirSimpleFunction): List<FirFunctionSymbol<*>> {
processFunctionsByName(function.name) {}
return getDirectOverriddenFunctions(function.symbol)
}
private fun FirTypeScope.retrieveDirectOverriddenOf(property: FirProperty): List<FirPropertySymbol> {
processPropertiesByName(property.name) {}
return getDirectOverriddenProperties(property.symbol)
private fun FirTypeScope.retrieveDirectOverriddenOf(member: FirCallableMemberDeclaration<*>): List<FirCallableSymbol<*>> {
return when (member) {
is FirSimpleFunction -> {
processFunctionsByName(member.name) {}
getDirectOverriddenFunctions(member.symbol)
}
is FirProperty -> {
processPropertiesByName(member.name) {}
getDirectOverriddenProperties(member.symbol)
}
else -> throw IllegalArgumentException("unexpected member kind $member")
}
}
private fun ConeKotlinType.substituteAllTypeParameters(
@@ -160,80 +165,49 @@ object FirOverrideChecker : FirClassChecker() {
return null
}
private fun checkFunction(
function: FirSimpleFunction,
private fun checkMember(
member: FirCallableMemberDeclaration<*>,
reporter: DiagnosticReporter,
typeCheckerContext: AbstractTypeCheckerContext,
firTypeScope: FirTypeScope,
context: CheckerContext,
) {
if (!function.isOverride) {
if (!member.isOverride) {
return
}
val overriddenFunctionSymbols = firTypeScope.retrieveDirectOverriddenOf(function)
val overriddenMemberSymbols = firTypeScope.retrieveDirectOverriddenOf(member)
if (overriddenFunctionSymbols.isEmpty()) {
reporter.reportNothingToOverride(function, context)
if (overriddenMemberSymbols.isEmpty()) {
reporter.reportNothingToOverride(member, context)
return
}
checkModality(overriddenFunctionSymbols)?.let {
reporter.reportOverridingFinalMember(function, it, context)
checkModality(overriddenMemberSymbols)?.let {
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(
overriddenSymbols = overriddenFunctionSymbols,
member.checkVisibility(reporter, overriddenMemberSymbols, context)
val restriction = member.checkReturnType(
overriddenSymbols = overriddenMemberSymbols,
typeCheckerContext = typeCheckerContext,
context = context,
)
restriction?.let {
reporter.reportReturnTypeMismatchOnFunction(function, it, context)
}
}
private fun checkProperty(
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)
) ?: return
when (member) {
is FirSimpleFunction -> reporter.reportReturnTypeMismatchOnFunction(member, restriction, context)
is FirProperty -> {
if (member.isVar) {
reporter.reportTypeMismatchOnVariable(member, restriction, context)
} else {
reporter.reportTypeMismatchOnProperty(member, restriction, context)
}
}
}
}
@@ -3,5 +3,8 @@
Compiling files:
src/Sub.kt
End of files
Exit code: OK
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
'y' hides member of supertype 'Super' and needs 'override' modifier