[ObjCInterop] Implement @ObjCSignatureOverride
This annotation leads to conflicting overloads error supression,
in case where several function with the same argument types,
but different argument names are inherited from ObjC class.
We need to implement it in both K1 and K2 to make the IDE experience
better.
But the annotation itself wouldn't be available in K1.
^KT-61323
This commit is contained in:
committed by
Space Team
parent
77eee0d3fc
commit
6e8a7d4662
+4
@@ -103,5 +103,9 @@ object NATIVE_DIAGNOSTICS_LIST : DiagnosticList("FirNativeErrors") {
|
||||
val CONSTRUCTOR_MATCHES_SEVERAL_SUPER_CONSTRUCTORS by error<KtElement>() {
|
||||
parameter<FqName>("annotation")
|
||||
}
|
||||
val CONFLICTING_OBJC_OVERLOADS by error<PsiElement>() {
|
||||
parameter<Collection<Symbol>>("conflictingOverloads")
|
||||
}
|
||||
val INAPPLICABLE_OBJC_OVERRIDE by error<PsiElement>()
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -62,6 +62,8 @@ object FirNativeErrors {
|
||||
val CONSTRUCTOR_OVERRIDES_ALREADY_OVERRIDDEN_OBJC_INITIALIZER: KtDiagnosticFactory1<FqName> by error1<KtElement, FqName>()
|
||||
val CONSTRUCTOR_DOES_NOT_OVERRIDE_ANY_SUPER_CONSTRUCTOR: KtDiagnosticFactory1<FqName> by error1<KtElement, FqName>()
|
||||
val CONSTRUCTOR_MATCHES_SEVERAL_SUPER_CONSTRUCTORS: KtDiagnosticFactory1<FqName> by error1<KtElement, FqName>()
|
||||
val CONFLICTING_OBJC_OVERLOADS: KtDiagnosticFactory1<Collection<FirBasedSymbol<*>>> by error1<PsiElement, Collection<FirBasedSymbol<*>>>()
|
||||
val INAPPLICABLE_OBJC_OVERRIDE: KtDiagnosticFactory0 by error0<PsiElement>()
|
||||
|
||||
init {
|
||||
RootDiagnosticRendererFactory.registerFactory(FirNativeErrorsDefaultMessages)
|
||||
|
||||
+11
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOLS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors.CANNOT_CHECK_FOR_FORWARD_DECLARATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors.CONFLICTING_OBJC_OVERLOADS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors.CONSTRUCTOR_DOES_NOT_OVERRIDE_ANY_SUPER_CONSTRUCTOR
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors.CONSTRUCTOR_MATCHES_SEVERAL_SUPER_CONSTRUCTORS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors.CONSTRUCTOR_OVERRIDES_ALREADY_OVERRIDDEN_OBJC_INITIALIZER
|
||||
@@ -20,6 +21,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors.FORW
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors.FORWARD_DECLARATION_AS_REIFIED_TYPE_ARGUMENT
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors.INAPPLICABLE_EXACT_OBJC_NAME
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors.INAPPLICABLE_OBJC_NAME
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors.INAPPLICABLE_OBJC_OVERRIDE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors.INAPPLICABLE_SHARED_IMMUTABLE_PROPERTY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors.INAPPLICABLE_SHARED_IMMUTABLE_TOP_LEVEL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors.INAPPLICABLE_THREAD_LOCAL
|
||||
@@ -145,5 +147,14 @@ object FirNativeErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
"Constructor with ''@{0}'' matches more than one of super constructors.",
|
||||
TO_STRING
|
||||
)
|
||||
map.put(
|
||||
CONFLICTING_OBJC_OVERLOADS,
|
||||
"Conflicting overloads: {0}. Add @ObjCSignatureOverride to allow collision for functions inherited from Objective-C.",
|
||||
SYMBOLS
|
||||
)
|
||||
map.put(
|
||||
INAPPLICABLE_OBJC_OVERRIDE,
|
||||
"@ObjCSignatureOverride is only allowed on methods overriding methods from Objective-C.",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.fir.analysis.native.checkers
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory1
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirFunctionChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.PlatformConflictDeclarationsDiagnosticDispatcher
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors
|
||||
import org.jetbrains.kotlin.fir.backend.native.interop.getObjCMethodInfoFromOverriddenFunctions
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.name.NativeStandardInteropNames.Annotations.objCSignatureOverrideClassId
|
||||
import org.jetbrains.kotlin.utils.SmartSet
|
||||
|
||||
private fun FirFunctionSymbol<*>.isInheritedFromObjc(context: CheckerContext): Boolean {
|
||||
return getObjCMethodInfoFromOverriddenFunctions(context.session, context.scopeSession) != null
|
||||
}
|
||||
|
||||
/**
|
||||
* This function basically checks that these two functions have different objective-C signature.
|
||||
*
|
||||
* This signature consists of function name and parameter names except first.
|
||||
*
|
||||
* So we ignore the first parameter name, but check others
|
||||
*/
|
||||
private fun FirFunctionSymbol<*>.hasDifferentParameterNames(other: FirFunctionSymbol<*>) : Boolean {
|
||||
return valueParameterSymbols.drop(1).map { it.name } != other.valueParameterSymbols.drop(1).map { it.name }
|
||||
}
|
||||
|
||||
object NativeConflictDeclarationsDiagnosticDispatcher : PlatformConflictDeclarationsDiagnosticDispatcher {
|
||||
override fun getDiagnostic(
|
||||
conflictingDeclaration: FirBasedSymbol<*>,
|
||||
symbols: SmartSet<FirBasedSymbol<*>>,
|
||||
context: CheckerContext
|
||||
): KtDiagnosticFactory1<Collection<FirBasedSymbol<*>>>? {
|
||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.ObjCSignatureOverrideAnnotation)) {
|
||||
if (conflictingDeclaration is FirFunctionSymbol<*> && symbols.all { it is FirFunctionSymbol<*> }) {
|
||||
if (conflictingDeclaration.isInheritedFromObjc(context) && symbols.all { (it as FirFunctionSymbol<*>).isInheritedFromObjc(context) }) {
|
||||
if (symbols.all { (it as FirFunctionSymbol<*>).hasDifferentParameterNames(conflictingDeclaration) }) {
|
||||
if (conflictingDeclaration.hasAnnotation(objCSignatureOverrideClassId, context.session)) {
|
||||
return null
|
||||
} else {
|
||||
return FirNativeErrors.CONFLICTING_OBJC_OVERLOADS
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return PlatformConflictDeclarationsDiagnosticDispatcher.DEFAULT.getDiagnostic(conflictingDeclaration, symbols, context)
|
||||
}
|
||||
}
|
||||
|
||||
object FirNativeObjcOverrideApplicabilityChecker : FirFunctionChecker(MppCheckerKind.Platform) {
|
||||
override fun check(
|
||||
declaration: FirFunction,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter,
|
||||
) {
|
||||
if (declaration.hasAnnotation(objCSignatureOverrideClassId, context.session)) {
|
||||
if (!declaration.symbol.isInheritedFromObjc(context)) {
|
||||
reporter.reportOn(declaration.getAnnotationByClassId(objCSignatureOverrideClassId, context.session)?.source, FirNativeErrors.INAPPLICABLE_OBJC_OVERRIDE, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -15,7 +15,12 @@ object NativeDeclarationCheckers : DeclarationCheckers() {
|
||||
FirNativeSharedImmutableChecker,
|
||||
FirNativeThreadLocalChecker,
|
||||
FirNativeIdentifierChecker,
|
||||
FirNativeObjCNameChecker
|
||||
FirNativeObjCNameChecker,
|
||||
)
|
||||
|
||||
override val functionCheckers: Set<FirFunctionChecker>
|
||||
get() = setOf(
|
||||
FirNativeObjcOverrideApplicabilityChecker
|
||||
)
|
||||
|
||||
override val callableDeclarationCheckers: Set<FirCallableDeclarationChecker>
|
||||
|
||||
+2
@@ -679,6 +679,8 @@ val FIR_NON_SUPPRESSIBLE_ERROR_NAMES: Set<String> = setOf(
|
||||
"CONSTRUCTOR_OVERRIDES_ALREADY_OVERRIDDEN_OBJC_INITIALIZER",
|
||||
"CONSTRUCTOR_DOES_NOT_OVERRIDE_ANY_SUPER_CONSTRUCTOR",
|
||||
"CONSTRUCTOR_MATCHES_SEVERAL_SUPER_CONSTRUCTORS",
|
||||
"CONFLICTING_OBJC_OVERLOADS",
|
||||
"INAPPLICABLE_OBJC_OVERRIDE",
|
||||
"NESTED_EXTERNAL_DECLARATION",
|
||||
"WRONG_EXTERNAL_DECLARATION",
|
||||
"NESTED_CLASS_IN_EXTERNAL_INTERFACE",
|
||||
|
||||
+47
-19
@@ -6,9 +6,13 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory1
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.FirNameConflictsTrackerComponent
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
@@ -18,14 +22,43 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.PACKAGE_MEMBER
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.typeAliasForConstructor
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.utils.SmartSet
|
||||
|
||||
interface PlatformConflictDeclarationsDiagnosticDispatcher : FirSessionComponent {
|
||||
fun getDiagnostic(
|
||||
conflictingDeclaration: FirBasedSymbol<*>,
|
||||
symbols: SmartSet<FirBasedSymbol<*>>,
|
||||
context: CheckerContext
|
||||
): KtDiagnosticFactory1<Collection<FirBasedSymbol<*>>>?
|
||||
|
||||
object DEFAULT : PlatformConflictDeclarationsDiagnosticDispatcher {
|
||||
override fun getDiagnostic(
|
||||
conflictingDeclaration: FirBasedSymbol<*>,
|
||||
symbols: SmartSet<FirBasedSymbol<*>>,
|
||||
context: CheckerContext
|
||||
): KtDiagnosticFactory1<Collection<FirBasedSymbol<*>>> {
|
||||
return when {
|
||||
conflictingDeclaration is FirNamedFunctionSymbol || conflictingDeclaration is FirConstructorSymbol -> {
|
||||
FirErrors.CONFLICTING_OVERLOADS
|
||||
}
|
||||
conflictingDeclaration is FirClassLikeSymbol<*> &&
|
||||
conflictingDeclaration.getContainingClassSymbol(context.session) == null &&
|
||||
symbols.any { it is FirClassLikeSymbol<*> } -> {
|
||||
FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION
|
||||
}
|
||||
else -> {
|
||||
FirErrors.REDECLARATION
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val FirSession.conflictDeclarationsDiagnosticDispatcher: PlatformConflictDeclarationsDiagnosticDispatcher? by FirSession.nullableSessionComponentAccessor()
|
||||
|
||||
object FirConflictsDeclarationChecker : FirBasicDeclarationChecker(MppCheckerKind.Platform) {
|
||||
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
when (declaration) {
|
||||
@@ -90,21 +123,16 @@ object FirConflictsDeclarationChecker : FirBasicDeclarationChecker(MppCheckerKin
|
||||
conflictingDeclaration.isPrimaryConstructor && symbols.all { it.isPrimaryConstructor }
|
||||
) return@forEach
|
||||
|
||||
when {
|
||||
symbols.singleOrNull()?.let { isExpectAndActual(conflictingDeclaration, it) } == true -> {
|
||||
reporter.reportOn(source, FirErrors.EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE, conflictingDeclaration, context)
|
||||
}
|
||||
conflictingDeclaration is FirNamedFunctionSymbol || conflictingDeclaration is FirConstructorSymbol -> {
|
||||
reporter.reportOn(source, FirErrors.CONFLICTING_OVERLOADS, symbols, context)
|
||||
}
|
||||
conflictingDeclaration is FirClassLikeSymbol<*> &&
|
||||
conflictingDeclaration.getContainingClassSymbol(context.session) == null &&
|
||||
symbols.any { it is FirClassLikeSymbol<*> } -> {
|
||||
reporter.reportOn(source, FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION, symbols, context)
|
||||
}
|
||||
else -> {
|
||||
reporter.reportOn(source, FirErrors.REDECLARATION, symbols, context)
|
||||
}
|
||||
if (symbols.singleOrNull()?.let { isExpectAndActual(conflictingDeclaration, it) } == true) {
|
||||
reporter.reportOn(source, FirErrors.EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE, conflictingDeclaration, context)
|
||||
return@forEach
|
||||
}
|
||||
|
||||
val dispatcher = context.session.conflictDeclarationsDiagnosticDispatcher ?: PlatformConflictDeclarationsDiagnosticDispatcher.DEFAULT
|
||||
val factory = dispatcher.getDiagnostic(conflictingDeclaration, symbols, context)
|
||||
|
||||
if (factory != null) {
|
||||
reporter.reportOn(source, factory, symbols, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-3
@@ -7,23 +7,25 @@ package org.jetbrains.kotlin.fir.session
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.PlatformConflictDeclarationsDiagnosticDispatcher
|
||||
import org.jetbrains.kotlin.fir.analysis.native.checkers.FirNativeCastChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.native.checkers.NativeConflictDeclarationsDiagnosticDispatcher
|
||||
import org.jetbrains.kotlin.fir.backend.native.FirNativeClassMapper
|
||||
import org.jetbrains.kotlin.fir.backend.native.FirNativeOverrideChecker
|
||||
import org.jetbrains.kotlin.fir.checkers.registerNativeCheckers
|
||||
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirBuiltinSyntheticFunctionInterfaceProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker
|
||||
import org.jetbrains.kotlin.fir.scopes.FirPlatformClassMapper
|
||||
import org.jetbrains.kotlin.fir.session.FirSessionFactoryHelper.registerDefaultComponents
|
||||
import org.jetbrains.kotlin.library.isNativeStdlib
|
||||
import org.jetbrains.kotlin.library.metadata.impl.KlibResolvedModuleDescriptorsFactoryImpl.Companion.FORWARD_DECLARATIONS_MODULE_NAME
|
||||
import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
object FirNativeSessionFactory : FirAbstractSessionFactory() {
|
||||
@OptIn(SessionConfiguration::class)
|
||||
fun createLibrarySession(
|
||||
mainModuleName: Name,
|
||||
resolvedLibraries: List<KotlinResolvedLibrary>,
|
||||
@@ -63,7 +65,6 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
|
||||
})
|
||||
}
|
||||
|
||||
@OptIn(SessionConfiguration::class)
|
||||
fun createModuleBasedSession(
|
||||
moduleData: FirModuleData,
|
||||
sessionProvider: FirProjectSessionProvider,
|
||||
@@ -102,5 +103,7 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
|
||||
fun FirSession.registerNativeComponents() {
|
||||
register(FirPlatformClassMapper::class, FirNativeClassMapper())
|
||||
register(FirPlatformSpecificCastChecker::class, FirNativeCastChecker)
|
||||
register(PlatformConflictDeclarationsDiagnosticDispatcher::class, NativeConflictDeclarationsDiagnosticDispatcher)
|
||||
register(FirOverrideChecker::class, FirNativeOverrideChecker(this))
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.name.NativeStandardInteropNames
|
||||
import org.jetbrains.kotlin.native.interop.ObjCMethodInfo
|
||||
|
||||
|
||||
internal fun FirFunctionSymbol<*>.getObjCMethodInfoFromOverriddenFunctions(session: FirSession, scopeSession: ScopeSession): ObjCMethodInfo? {
|
||||
fun FirFunctionSymbol<*>.getObjCMethodInfoFromOverriddenFunctions(session: FirSession, scopeSession: ScopeSession): ObjCMethodInfo? {
|
||||
decodeObjCMethodAnnotation(session)?.let {
|
||||
return it
|
||||
}
|
||||
|
||||
@@ -16,9 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.container.DefaultImplementation
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.diagnostics.reportOnDeclaration
|
||||
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
||||
@@ -30,11 +33,35 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.platform
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import java.util.*
|
||||
|
||||
@DefaultImplementation(impl = ConflictingOverloadsDispatcher.Default::class)
|
||||
interface ConflictingOverloadsDispatcher {
|
||||
fun getDiagnostic(
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
declaration: DeclarationDescriptor,
|
||||
redeclarations: Collection<DeclarationDescriptor>
|
||||
): DiagnosticFactory1<PsiElement, Collection<DeclarationDescriptor>>?
|
||||
|
||||
object Default : ConflictingOverloadsDispatcher {
|
||||
override fun getDiagnostic(
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
declaration: DeclarationDescriptor,
|
||||
redeclarations: Collection<DeclarationDescriptor>
|
||||
): DiagnosticFactory1<PsiElement, Collection<DeclarationDescriptor>>? {
|
||||
return when (declaration) {
|
||||
is PropertyDescriptor, is ClassifierDescriptor -> Errors.REDECLARATION
|
||||
is FunctionDescriptor -> Errors.CONFLICTING_OVERLOADS
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class OverloadResolver(
|
||||
private val trace: BindingTrace,
|
||||
private val overloadFilter: OverloadFilter,
|
||||
private val overloadChecker: OverloadChecker,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
private val errorDispatcher: ConflictingOverloadsDispatcher,
|
||||
private val languageVersionSettings: LanguageVersionSettings,
|
||||
mainFunctionDetectorFactory: MainFunctionDetector.Factory
|
||||
) {
|
||||
|
||||
@@ -299,12 +326,9 @@ class OverloadResolver(
|
||||
if (redeclarations.isEmpty()) return
|
||||
|
||||
for (memberDescriptor in redeclarations) {
|
||||
when (memberDescriptor) {
|
||||
is PropertyDescriptor,
|
||||
is ClassifierDescriptor ->
|
||||
reportOnDeclaration(trace, memberDescriptor) { Errors.REDECLARATION.on(it, redeclarations) }
|
||||
is FunctionDescriptor ->
|
||||
reportOnDeclaration(trace, memberDescriptor) { Errors.CONFLICTING_OVERLOADS.on(it, redeclarations) }
|
||||
val diagnostic = errorDispatcher.getDiagnostic(languageVersionSettings, memberDescriptor, redeclarations) ?: continue
|
||||
reportOnDeclaration(trace, memberDescriptor) {
|
||||
diagnostic.on(it, redeclarations)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,28 +42,34 @@ headerFilter = lib.h
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import lib.ObjCClass
|
||||
// required for K1
|
||||
@file:Suppress("CONFLICTING_OVERLOADS", "UNRESOLVED_REFERENCE", "API_NOT_AVAILABLE")
|
||||
|
||||
import lib.ObjCClass
|
||||
import kotlinx.cinterop.ObjCSignatureOverride
|
||||
|
||||
@Suppress("CONFLICTING_OVERLOADS")
|
||||
class OverrideAll : ObjCClass() {
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(arg: Int, arg2: String?) = "D"
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(ohNoOtherName: Int, name2: String?) = "E"
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(arg: Int, name3: String?) = "F"
|
||||
}
|
||||
|
||||
@Suppress("CONFLICTING_OVERLOADS")
|
||||
class OverrideNone : ObjCClass() {
|
||||
}
|
||||
|
||||
@Suppress("CONFLICTING_OVERLOADS")
|
||||
class OverrideOne : ObjCClass() {
|
||||
override fun fooWithArg(arg: Int, arg2: String?) = "G"
|
||||
}
|
||||
|
||||
@Suppress("CONFLICTING_OVERLOADS")
|
||||
class OverrideWithDifferentFirstArgName : ObjCClass() {
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(a: Int, arg2: String?) = "H"
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(b: Int, name2: String?) = "I"
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(c: Int, name3: String?) = "J"
|
||||
}
|
||||
|
||||
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
// !LANGUAGE: -ObjCSignatureOverrideAnnotation
|
||||
// FIR_IDENTICAL
|
||||
// WITH_PLATFORM_LIBS
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import platform.darwin.*
|
||||
import platform.Foundation.*
|
||||
import platform.CoreFoundation.*
|
||||
import platform.CoreBluetooth.*
|
||||
|
||||
class Delelegate1 : CBCentralManagerDelegateProtocol, NSObject() {
|
||||
override fun centralManager(central: CBCentralManager, willRestoreState: Map<Any?, *>): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDiscoverPeripheral: CBPeripheral,
|
||||
advertisementData: Map<Any?, *>,
|
||||
RSSI: NSNumber
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManager(central: CBCentralManager, didConnectPeripheral: CBPeripheral): Unit = TODO()
|
||||
<!CONFLICTING_OVERLOADS!>override fun centralManager(central: CBCentralManager, didFailToConnectPeripheral: CBPeripheral, error: NSError?): Unit<!> = TODO()
|
||||
<!CONFLICTING_OVERLOADS!>override fun centralManager(central: CBCentralManager, didDisconnectPeripheral: CBPeripheral, error: NSError?): Unit<!> = TODO()
|
||||
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDisconnectPeripheral: CBPeripheral,
|
||||
timestamp: Double,
|
||||
isReconnecting: Boolean,
|
||||
error: NSError?
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManagerDidUpdateState(central: CBCentralManager): Unit = TODO()
|
||||
}
|
||||
|
||||
class Delegate2 : CBCentralManagerDelegateProtocol, NSObject() {
|
||||
override fun centralManager(central: CBCentralManager, willRestoreState: Map<Any?, *>): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDiscoverPeripheral: CBPeripheral,
|
||||
advertisementData: Map<Any?, *>,
|
||||
RSSI: NSNumber
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManager(central: CBCentralManager, didConnectPeripheral: CBPeripheral): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDisconnectPeripheral: CBPeripheral,
|
||||
timestamp: Double,
|
||||
isReconnecting: Boolean,
|
||||
error: NSError?
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManagerDidUpdateState(central: CBCentralManager): Unit = TODO()
|
||||
|
||||
<!CONFLICTING_OVERLOADS!>override fun centralManager(central: CBCentralManager, didFailToConnectPeripheral: CBPeripheral, error: NSError?): Unit<!> = TODO()
|
||||
<!CONFLICTING_OVERLOADS!>override fun centralManager(central: CBCentralManager, didDisconnectPeripheral: CBPeripheral, error: NSError?): Unit<!> = TODO()
|
||||
}
|
||||
|
||||
class Delegate3 : CBCentralManagerDelegateProtocol, NSObject() {
|
||||
override fun centralManager(central: CBCentralManager, willRestoreState: Map<Any?, *>): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDiscoverPeripheral: CBPeripheral,
|
||||
advertisementData: Map<Any?, *>,
|
||||
RSSI: NSNumber
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManager(central: CBCentralManager, didConnectPeripheral: CBPeripheral): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDisconnectPeripheral: CBPeripheral,
|
||||
timestamp: Double,
|
||||
isReconnecting: Boolean,
|
||||
error: NSError?
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManagerDidUpdateState(central: CBCentralManager): Unit = TODO()
|
||||
|
||||
<!CONFLICTING_OVERLOADS!>override fun centralManager(central: CBCentralManager, didFailToConnectPeripheral: CBPeripheral, error: NSError?): Unit<!> = TODO()
|
||||
<!CONFLICTING_OVERLOADS!>override fun centralManager(central: CBCentralManager, didDisconnectPeripheral: CBPeripheral, error: NSError?): Unit<!> = TODO()
|
||||
}
|
||||
|
||||
class Delegate4 : CBCentralManagerDelegateProtocol, NSObject() {
|
||||
override fun centralManager(central: CBCentralManager, willRestoreState: Map<Any?, *>): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDiscoverPeripheral: CBPeripheral,
|
||||
advertisementData: Map<Any?, *>,
|
||||
RSSI: NSNumber
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManager(central: CBCentralManager, didConnectPeripheral: CBPeripheral): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDisconnectPeripheral: CBPeripheral,
|
||||
timestamp: Double,
|
||||
isReconnecting: Boolean,
|
||||
error: NSError?
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManagerDidUpdateState(central: CBCentralManager): Unit = TODO()
|
||||
|
||||
<!CONFLICTING_OVERLOADS!>override fun centralManager(central: CBCentralManager, didFailToConnectPeripheral: CBPeripheral, error: NSError?): Unit<!> = TODO()
|
||||
<!CONFLICTING_OVERLOADS!>override fun centralManager(central: CBCentralManager, didDisconnectPeripheral: CBPeripheral, error: NSError?): Unit<!> = TODO()
|
||||
}
|
||||
|
||||
class Delegate5 : CBCentralManagerDelegateProtocol, NSObject() {
|
||||
override fun centralManager(central: CBCentralManager, willRestoreState: Map<Any?, *>): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDiscoverPeripheral: CBPeripheral,
|
||||
advertisementData: Map<Any?, *>,
|
||||
RSSI: NSNumber
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManager(central: CBCentralManager, didConnectPeripheral: CBPeripheral): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDisconnectPeripheral: CBPeripheral,
|
||||
timestamp: Double,
|
||||
isReconnecting: Boolean,
|
||||
error: NSError?
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManagerDidUpdateState(central: CBCentralManager): Unit = TODO()
|
||||
|
||||
<!CONFLICTING_OVERLOADS!>override fun centralManager(central: CBCentralManager, didFailToConnectPeripheral: CBPeripheral, error: NSError?): Unit<!> = TODO()
|
||||
<!CONFLICTING_OVERLOADS!>override fun centralManager(central: CBCentralManager, didFailToConnectPeripheral: CBPeripheral, error: NSError?): Unit<!> = TODO()
|
||||
<!CONFLICTING_OVERLOADS!>override fun centralManager(central: CBCentralManager, didDisconnectPeripheral: CBPeripheral, error: NSError?): Unit<!> = TODO()
|
||||
}
|
||||
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
// !LANGUAGE: +ObjCSignatureOverrideAnnotation
|
||||
// !API_VERSION: 2.0
|
||||
// FIR_IDENTICAL
|
||||
// WITH_PLATFORM_LIBS
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import platform.darwin.*
|
||||
import platform.Foundation.*
|
||||
import platform.CoreFoundation.*
|
||||
import platform.CoreBluetooth.*
|
||||
|
||||
class Delelegate1 : CBCentralManagerDelegateProtocol, NSObject() {
|
||||
override fun centralManager(central: CBCentralManager, willRestoreState: Map<Any?, *>): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDiscoverPeripheral: CBPeripheral,
|
||||
advertisementData: Map<Any?, *>,
|
||||
RSSI: NSNumber
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManager(central: CBCentralManager, didConnectPeripheral: CBPeripheral): Unit = TODO()
|
||||
@ObjCSignatureOverride
|
||||
override fun centralManager(central: CBCentralManager, didFailToConnectPeripheral: CBPeripheral, error: NSError?): Unit = TODO()
|
||||
@ObjCSignatureOverride
|
||||
override fun centralManager(central: CBCentralManager, didDisconnectPeripheral: CBPeripheral, error: NSError?): Unit = TODO()
|
||||
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDisconnectPeripheral: CBPeripheral,
|
||||
timestamp: Double,
|
||||
isReconnecting: Boolean,
|
||||
error: NSError?
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManagerDidUpdateState(central: CBCentralManager): Unit = TODO()
|
||||
}
|
||||
|
||||
class Delegate2 : CBCentralManagerDelegateProtocol, NSObject() {
|
||||
override fun centralManager(central: CBCentralManager, willRestoreState: Map<Any?, *>): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDiscoverPeripheral: CBPeripheral,
|
||||
advertisementData: Map<Any?, *>,
|
||||
RSSI: NSNumber
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManager(central: CBCentralManager, didConnectPeripheral: CBPeripheral): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDisconnectPeripheral: CBPeripheral,
|
||||
timestamp: Double,
|
||||
isReconnecting: Boolean,
|
||||
error: NSError?
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManagerDidUpdateState(central: CBCentralManager): Unit = TODO()
|
||||
|
||||
<!CONFLICTING_OBJC_OVERLOADS!>override fun centralManager(central: CBCentralManager, didFailToConnectPeripheral: CBPeripheral, error: NSError?): Unit = TODO()<!>
|
||||
<!CONFLICTING_OBJC_OVERLOADS!>override fun centralManager(central: CBCentralManager, didDisconnectPeripheral: CBPeripheral, error: NSError?): Unit = TODO()<!>
|
||||
}
|
||||
|
||||
class Delegate3 : CBCentralManagerDelegateProtocol, NSObject() {
|
||||
override fun centralManager(central: CBCentralManager, willRestoreState: Map<Any?, *>): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDiscoverPeripheral: CBPeripheral,
|
||||
advertisementData: Map<Any?, *>,
|
||||
RSSI: NSNumber
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManager(central: CBCentralManager, didConnectPeripheral: CBPeripheral): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDisconnectPeripheral: CBPeripheral,
|
||||
timestamp: Double,
|
||||
isReconnecting: Boolean,
|
||||
error: NSError?
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManagerDidUpdateState(central: CBCentralManager): Unit = TODO()
|
||||
|
||||
@ObjCSignatureOverride
|
||||
override fun centralManager(central: CBCentralManager, didFailToConnectPeripheral: CBPeripheral, error: NSError?): Unit = TODO()
|
||||
<!CONFLICTING_OBJC_OVERLOADS!>override fun centralManager(central: CBCentralManager, didDisconnectPeripheral: CBPeripheral, error: NSError?): Unit = TODO()<!>
|
||||
}
|
||||
|
||||
class Delegate4 : CBCentralManagerDelegateProtocol, NSObject() {
|
||||
override fun centralManager(central: CBCentralManager, willRestoreState: Map<Any?, *>): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDiscoverPeripheral: CBPeripheral,
|
||||
advertisementData: Map<Any?, *>,
|
||||
RSSI: NSNumber
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManager(central: CBCentralManager, didConnectPeripheral: CBPeripheral): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDisconnectPeripheral: CBPeripheral,
|
||||
timestamp: Double,
|
||||
isReconnecting: Boolean,
|
||||
error: NSError?
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManagerDidUpdateState(central: CBCentralManager): Unit = TODO()
|
||||
|
||||
@ObjCSignatureOverride
|
||||
override fun centralManager(central: CBCentralManager, didFailToConnectPeripheral: CBPeripheral, error: NSError?): Unit = TODO()
|
||||
@ObjCSignatureOverride
|
||||
override fun centralManager(central: CBCentralManager, didDisconnectPeripheral: CBPeripheral, error: NSError?): Unit = TODO()
|
||||
}
|
||||
|
||||
class Delegate5 : CBCentralManagerDelegateProtocol, NSObject() {
|
||||
override fun centralManager(central: CBCentralManager, willRestoreState: Map<Any?, *>): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDiscoverPeripheral: CBPeripheral,
|
||||
advertisementData: Map<Any?, *>,
|
||||
RSSI: NSNumber
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManager(central: CBCentralManager, didConnectPeripheral: CBPeripheral): Unit = TODO()
|
||||
override fun centralManager(
|
||||
central: CBCentralManager,
|
||||
didDisconnectPeripheral: CBPeripheral,
|
||||
timestamp: Double,
|
||||
isReconnecting: Boolean,
|
||||
error: NSError?
|
||||
): Unit = TODO()
|
||||
|
||||
override fun centralManagerDidUpdateState(central: CBCentralManager): Unit = TODO()
|
||||
|
||||
<!CONFLICTING_OVERLOADS!>@ObjCSignatureOverride
|
||||
override fun centralManager(central: CBCentralManager, didFailToConnectPeripheral: CBPeripheral, error: NSError?): Unit<!> = TODO()
|
||||
<!CONFLICTING_OVERLOADS!>@ObjCSignatureOverride
|
||||
override fun centralManager(central: CBCentralManager, didFailToConnectPeripheral: CBPeripheral, error: NSError?): Unit<!> = TODO()
|
||||
@ObjCSignatureOverride
|
||||
override fun centralManager(central: CBCentralManager, didDisconnectPeripheral: CBPeripheral, error: NSError?): Unit = TODO()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// !API_VERSION: 2.0
|
||||
// FIR_IDENTICAL
|
||||
// WITH_PLATFORM_LIBS
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import platform.darwin.*
|
||||
|
||||
<!INAPPLICABLE_OBJC_OVERRIDE!>@ObjCSignatureOverride<!>
|
||||
fun foo() = 1
|
||||
|
||||
class A {
|
||||
<!INAPPLICABLE_OBJC_OVERRIDE!>@ObjCSignatureOverride<!>
|
||||
fun foo() = 1
|
||||
}
|
||||
|
||||
<!WRONG_ANNOTATION_TARGET!>@ObjCSignatureOverride<!>
|
||||
class B : NSObject() {
|
||||
<!INAPPLICABLE_OBJC_OVERRIDE!>@ObjCSignatureOverride<!>
|
||||
fun foo() = 1
|
||||
<!WRONG_ANNOTATION_TARGET!>@ObjCSignatureOverride<!>
|
||||
val v = 1
|
||||
}
|
||||
@@ -310,6 +310,7 @@ enum class LanguageFeature(
|
||||
DisableCompatibilityModeForNewInference(KOTLIN_2_0, kind = OTHER), // KT-63558 (umbrella), KT-64306, KT-64307, KT-64308
|
||||
DfaBooleanVariables(KOTLIN_2_0), // KT-25747
|
||||
LightweightLambdas(KOTLIN_2_0, kind = OTHER), // KT-45375
|
||||
ObjCSignatureOverrideAnnotation(KOTLIN_2_0, sinceApiVersion = ApiVersion.KOTLIN_2_0, kind = OTHER), // KT-61323
|
||||
|
||||
// 2.1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user