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.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)
} }
} }
} }
@@ -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