[FE 1.0] Extract NativeObjCNameOverridesChecker from NativeObjCNameChecker
This commit is contained in:
+8
-37
@@ -16,17 +16,17 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.annotations.argumentValue
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
object NativeObjCNameChecker : DeclarationChecker {
|
||||
|
||||
private val objCNameFqName = FqName("kotlin.native.ObjCName")
|
||||
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
checkDeclaration(declaration, descriptor, context)
|
||||
checkOverrides(declaration, descriptor, context)
|
||||
checkFakeOverrides(declaration, descriptor, context)
|
||||
if (descriptor is CallableMemberDescriptor) {
|
||||
NativeObjCNameOverridesChecker.check(declaration, descriptor, context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkDeclaration(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
@@ -84,29 +84,7 @@ object NativeObjCNameChecker : DeclarationChecker {
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkOverrides(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
if (descriptor !is CallableMemberDescriptor || descriptor.overriddenDescriptors.isEmpty()) return
|
||||
val objCNames = descriptor.overriddenDescriptors.map { it.getFirstBaseDescriptor().getObjCNames() }
|
||||
if (!objCNames.allNamesEquals()) {
|
||||
val containingDeclarations = descriptor.overriddenDescriptors.map { it.containingDeclaration }
|
||||
context.trace.report(ErrorsNative.INCOMPATIBLE_OBJC_NAME_OVERRIDE.on(declaration, descriptor, containingDeclarations))
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkFakeOverrides(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
if (descriptor !is ClassDescriptor) return
|
||||
descriptor.defaultType.memberScope
|
||||
.getContributedDescriptors(DescriptorKindFilter.ALL, MemberScope.Companion.ALL_NAME_FILTER)
|
||||
.forEach {
|
||||
if (it !is CallableMemberDescriptor || it.kind.isReal) return@forEach
|
||||
checkOverrides(declaration, it, context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun CallableMemberDescriptor.getFirstBaseDescriptor(): CallableMemberDescriptor =
|
||||
if (overriddenDescriptors.isEmpty()) this else overriddenDescriptors.first().getFirstBaseDescriptor()
|
||||
|
||||
private class ObjCName(
|
||||
class ObjCName(
|
||||
val annotation: AnnotationDescriptor
|
||||
) {
|
||||
val name: String? = annotation.argumentValue("name")?.value?.safeAs<String>()?.takeIf { it.isNotBlank() }
|
||||
@@ -126,20 +104,13 @@ object NativeObjCNameChecker : DeclarationChecker {
|
||||
|
||||
private fun DeclarationDescriptor.getObjCName(): ObjCName? = annotations.findAnnotation(objCNameFqName)?.let(::ObjCName)
|
||||
|
||||
private fun DeclarationDescriptor.getObjCNames(): List<ObjCName?> = when (this) {
|
||||
fun DeclarationDescriptor.getObjCNames(): List<ObjCName?> = when (this) {
|
||||
is FunctionDescriptor -> buildList {
|
||||
add(getObjCName())
|
||||
add(extensionReceiverParameter?.getObjCName())
|
||||
valueParameters.forEach { add(it.getObjCName()) }
|
||||
}
|
||||
|
||||
else -> listOf(getObjCName())
|
||||
}
|
||||
|
||||
private fun List<List<ObjCName?>>.allNamesEquals(): Boolean {
|
||||
val first = this[0]
|
||||
for (i in 1 until size) {
|
||||
if (first != this[i]) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.konan.diagnostics
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.konan.diagnostics.NativeObjCNameChecker.getObjCNames
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
|
||||
object NativeObjCNameOverridesChecker : DeclarationChecker {
|
||||
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
if (descriptor !is ClassDescriptor) return
|
||||
descriptor.defaultType.memberScope
|
||||
.getContributedDescriptors(DescriptorKindFilter.ALL, MemberScope.Companion.ALL_NAME_FILTER)
|
||||
.forEach {
|
||||
if (it !is CallableMemberDescriptor || it.kind.isReal) return@forEach
|
||||
check(declaration, it, context)
|
||||
}
|
||||
}
|
||||
|
||||
fun check(declaration: KtDeclaration, descriptor: CallableMemberDescriptor, context: DeclarationCheckerContext) {
|
||||
if (descriptor.overriddenDescriptors.isEmpty()) return
|
||||
val objCNames = descriptor.overriddenDescriptors.map { it.getFirstBaseDescriptor().getObjCNames() }
|
||||
if (!objCNames.allNamesEquals()) {
|
||||
val containingDeclarations = descriptor.overriddenDescriptors.map { it.containingDeclaration }
|
||||
context.trace.report(ErrorsNative.INCOMPATIBLE_OBJC_NAME_OVERRIDE.on(declaration, descriptor, containingDeclarations))
|
||||
}
|
||||
}
|
||||
|
||||
private fun CallableMemberDescriptor.getFirstBaseDescriptor(): CallableMemberDescriptor =
|
||||
if (overriddenDescriptors.isEmpty()) this else overriddenDescriptors.first().getFirstBaseDescriptor()
|
||||
|
||||
private fun List<List<NativeObjCNameChecker.ObjCName?>>.allNamesEquals(): Boolean {
|
||||
val first = this[0]
|
||||
for (i in 1 until size) {
|
||||
if (first != this[i]) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -24,8 +24,9 @@ object NativePlatformConfigurator : PlatformConfiguratorBase(
|
||||
additionalDeclarationCheckers = listOf(
|
||||
NativeThrowsChecker, NativeSharedImmutableChecker,
|
||||
NativeTopLevelSingletonChecker, NativeThreadLocalChecker,
|
||||
NativeObjCNameChecker, NativeObjCRefinementChecker,
|
||||
NativeObjCRefinementAnnotationChecker, NativeObjCRefinementOverridesChecker
|
||||
NativeObjCNameChecker, NativeObjCNameOverridesChecker,
|
||||
NativeObjCRefinementChecker, NativeObjCRefinementAnnotationChecker,
|
||||
NativeObjCRefinementOverridesChecker
|
||||
)
|
||||
) {
|
||||
override fun configureModuleComponents(container: StorageComponentContainer) {
|
||||
|
||||
Reference in New Issue
Block a user