FIR checker: simplify isExpect|isExternal checks

Those resolve information are different from modality/visibility, which
could have conflicting modifiers.
This commit is contained in:
Jinseong Jeon
2021-03-03 15:09:28 -08:00
committed by Dmitriy Novozhilov
parent 774ba58062
commit 9badbfc30d
5 changed files with 12 additions and 19 deletions
@@ -36,22 +36,18 @@ private inline fun isInsideSpecificClass(
internal fun FirMemberDeclaration.isEffectivelyExpect(
containingClass: FirRegularClass?,
modifierList: FirModifierList? = null,
context: CheckerContext,
): Boolean {
val isExpect = this.isExpect || modifierList?.modifiers?.any { it.token == KtTokens.EXPECT_KEYWORD } == true
if (isExpect) return true
if (this.isExpect) return true
return containingClass != null && isInsideExpectClass(containingClass, context)
}
internal fun FirMemberDeclaration.isEffectivelyExternal(
containingClass: FirRegularClass?,
modifierList: FirModifierList? = null,
context: CheckerContext,
): Boolean {
val isExternal = this.isExternal || modifierList?.modifiers?.any { it.token == KtTokens.EXTERNAL_KEYWORD } == true
if (isExternal) return true
if (this.isExternal) return true
// NB: [MemberDescriptor.isEffectivelyExternal] checks property accessors for property and vice versa.
// But, raw FIR creation already did such upward/downward propagation of modifiers.
@@ -63,11 +59,10 @@ internal fun FirMemberDeclaration.isEffectivelyExternal(
internal fun checkExpectDeclarationVisibilityAndBody(
declaration: FirMemberDeclaration,
source: FirSourceElement,
modifierList: FirModifierList?,
reporter: DiagnosticReporter,
context: CheckerContext
) {
if (declaration.isExpect || modifierList?.modifiers?.any { it.token == KtTokens.EXPECT_KEYWORD } == true) {
if (declaration.isExpect) {
if (Visibilities.isPrivate(declaration.visibility)) {
reporter.reportOn(source, FirErrors.EXPECTED_PRIVATE_DECLARATION, context)
}
@@ -116,7 +111,7 @@ private fun checkPropertyInitializer(
}
}
val isExpect = property.isEffectivelyExpect(containingClass, modifierList, context)
val isExpect = property.isEffectivelyExpect(containingClass, context)
when {
property.initializer != null -> {
@@ -150,7 +145,7 @@ private fun checkPropertyInitializer(
}
}
else -> {
val isExternal = property.isEffectivelyExternal(containingClass, modifierList, context)
val isExternal = property.isEffectivelyExternal(containingClass, context)
if (backingFieldRequired && !inInterface && !property.isLateInit && !isExpect && !isInitialized && !isExternal) {
property.source?.let {
if (property.receiverTypeRef != null && !property.hasAccessorImplementation) {
@@ -50,7 +50,6 @@ object FirMemberFunctionsChecker : FirRegularClassChecker() {
}
val isInsideExpectClass = isInsideExpectClass(containingDeclaration, context)
val hasOpenModifier = modifierList?.modifiers?.any { it.token == KtTokens.OPEN_KEYWORD } == true
val isExternal = function.isExternal || modifierList?.modifiers?.any { it.token == KtTokens.EXTERNAL_KEYWORD } == true
if (!function.hasBody) {
if (containingDeclaration.isInterface) {
if (Visibilities.isPrivate(function.visibility)) {
@@ -59,11 +58,11 @@ object FirMemberFunctionsChecker : FirRegularClassChecker() {
if (!isInsideExpectClass && !hasAbstractModifier && hasOpenModifier) {
reporter.reportOn(source, FirErrors.REDUNDANT_OPEN_IN_INTERFACE, context)
}
} else if (!isInsideExpectClass && !hasAbstractModifier && !isExternal) {
} else if (!isInsideExpectClass && !hasAbstractModifier && !function.isExternal) {
reporter.reportOn(source, FirErrors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY, function, context)
}
}
checkExpectDeclarationVisibilityAndBody(function, source, modifierList, reporter, context)
checkExpectDeclarationVisibilityAndBody(function, source, reporter, context)
}
}
@@ -149,7 +149,7 @@ object FirMemberPropertiesChecker : FirRegularClassChecker() {
val modifierList = with(FirModifierList) { property.source.getModifierList() }
checkProperty(containingDeclaration, property, modifierList, isInitialized, reporter, context)
checkExpectDeclarationVisibilityAndBody(property, source, modifierList, reporter, context)
checkExpectDeclarationVisibilityAndBody(property, source, reporter, context)
val hasAbstractModifier = modifierList?.modifiers?.any { it.token == KtTokens.ABSTRACT_KEYWORD } == true
val isAbstract = property.isAbstract || hasAbstractModifier
@@ -30,12 +30,11 @@ object FirTopLevelFunctionsChecker : FirFileChecker() {
// So, our source of truth should be the full modifier list retrieved from the source.
val modifierList = with(FirModifierList) { source.getModifierList() }
if (modifierList?.modifiers?.any { it.token == KtTokens.ABSTRACT_KEYWORD } == true) return
if (function.isExternal || modifierList?.modifiers?.any { it.token == KtTokens.EXTERNAL_KEYWORD } == true) return
val isExpect = function.isExpect || modifierList?.modifiers?.any { it.token == KtTokens.EXPECT_KEYWORD } == true
if (!function.hasBody && !isExpect) {
if (function.isExternal) return
if (!function.hasBody && !function.isExpect) {
reporter.reportOn(source, FirErrors.NON_MEMBER_FUNCTION_NO_BODY, function, context)
}
checkExpectDeclarationVisibilityAndBody(function, source, modifierList, reporter, context)
checkExpectDeclarationVisibilityAndBody(function, source, reporter, context)
}
}
@@ -29,6 +29,6 @@ object FirTopLevelPropertiesChecker : FirFileChecker() {
val modifierList = with(FirModifierList) { source.getModifierList() }
checkProperty(null, property, modifierList, property.initializer != null, reporter, context)
checkExpectDeclarationVisibilityAndBody(property, source, modifierList, reporter, context)
checkExpectDeclarationVisibilityAndBody(property, source, reporter, context)
}
}