[FE 1.0] Extract NativeObjCNameOverridesChecker from NativeObjCNameChecker
This commit is contained in:
+7
-36
@@ -16,17 +16,17 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
|||||||
import org.jetbrains.kotlin.resolve.annotations.argumentValue
|
import org.jetbrains.kotlin.resolve.annotations.argumentValue
|
||||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
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
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
object NativeObjCNameChecker : DeclarationChecker {
|
object NativeObjCNameChecker : DeclarationChecker {
|
||||||
|
|
||||||
private val objCNameFqName = FqName("kotlin.native.ObjCName")
|
private val objCNameFqName = FqName("kotlin.native.ObjCName")
|
||||||
|
|
||||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||||
checkDeclaration(declaration, descriptor, context)
|
checkDeclaration(declaration, descriptor, context)
|
||||||
checkOverrides(declaration, descriptor, context)
|
if (descriptor is CallableMemberDescriptor) {
|
||||||
checkFakeOverrides(declaration, descriptor, context)
|
NativeObjCNameOverridesChecker.check(declaration, descriptor, context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkDeclaration(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
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) {
|
class ObjCName(
|
||||||
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(
|
|
||||||
val annotation: AnnotationDescriptor
|
val annotation: AnnotationDescriptor
|
||||||
) {
|
) {
|
||||||
val name: String? = annotation.argumentValue("name")?.value?.safeAs<String>()?.takeIf { it.isNotBlank() }
|
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.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 {
|
is FunctionDescriptor -> buildList {
|
||||||
add(getObjCName())
|
add(getObjCName())
|
||||||
add(extensionReceiverParameter?.getObjCName())
|
add(extensionReceiverParameter?.getObjCName())
|
||||||
valueParameters.forEach { add(it.getObjCName()) }
|
valueParameters.forEach { add(it.getObjCName()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> listOf(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(
|
additionalDeclarationCheckers = listOf(
|
||||||
NativeThrowsChecker, NativeSharedImmutableChecker,
|
NativeThrowsChecker, NativeSharedImmutableChecker,
|
||||||
NativeTopLevelSingletonChecker, NativeThreadLocalChecker,
|
NativeTopLevelSingletonChecker, NativeThreadLocalChecker,
|
||||||
NativeObjCNameChecker, NativeObjCRefinementChecker,
|
NativeObjCNameChecker, NativeObjCNameOverridesChecker,
|
||||||
NativeObjCRefinementAnnotationChecker, NativeObjCRefinementOverridesChecker
|
NativeObjCRefinementChecker, NativeObjCRefinementAnnotationChecker,
|
||||||
|
NativeObjCRefinementOverridesChecker
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
override fun configureModuleComponents(container: StorageComponentContainer) {
|
override fun configureModuleComponents(container: StorageComponentContainer) {
|
||||||
|
|||||||
Reference in New Issue
Block a user