[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
+18
@@ -68,6 +68,18 @@ public class LLFirNativeTestGenerated extends AbstractLLFirNativeTest {
|
|||||||
runTest("compiler/testData/diagnostics/nativeTests/nativeProtectedFunCall.kt");
|
runTest("compiler/testData/diagnostics/nativeTests/nativeProtectedFunCall.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("noObjcOverrideConflictingOverloadsDisabled.kt")
|
||||||
|
public void testNoObjcOverrideConflictingOverloadsDisabled() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/nativeTests/noObjcOverrideConflictingOverloadsDisabled.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("noObjcOverrideConflictingOverloadsEnabled.kt")
|
||||||
|
public void testNoObjcOverrideConflictingOverloadsEnabled() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/nativeTests/noObjcOverrideConflictingOverloadsEnabled.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("objCName.kt")
|
@TestMetadata("objCName.kt")
|
||||||
public void testObjCName() throws Exception {
|
public void testObjCName() throws Exception {
|
||||||
@@ -104,6 +116,12 @@ public class LLFirNativeTestGenerated extends AbstractLLFirNativeTest {
|
|||||||
runTest("compiler/testData/diagnostics/nativeTests/objCRefinement.kt");
|
runTest("compiler/testData/diagnostics/nativeTests/objCRefinement.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("objcOverrideApplicability.kt")
|
||||||
|
public void testObjcOverrideApplicability() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/nativeTests/objcOverrideApplicability.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("resolveToDelegatedProperty.kt")
|
@TestMetadata("resolveToDelegatedProperty.kt")
|
||||||
public void testResolveToDelegatedProperty() throws Exception {
|
public void testResolveToDelegatedProperty() throws Exception {
|
||||||
|
|||||||
+18
@@ -68,6 +68,18 @@ public class LLFirReversedNativeTestGenerated extends AbstractLLFirReversedNativ
|
|||||||
runTest("compiler/testData/diagnostics/nativeTests/nativeProtectedFunCall.kt");
|
runTest("compiler/testData/diagnostics/nativeTests/nativeProtectedFunCall.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("noObjcOverrideConflictingOverloadsDisabled.kt")
|
||||||
|
public void testNoObjcOverrideConflictingOverloadsDisabled() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/nativeTests/noObjcOverrideConflictingOverloadsDisabled.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("noObjcOverrideConflictingOverloadsEnabled.kt")
|
||||||
|
public void testNoObjcOverrideConflictingOverloadsEnabled() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/nativeTests/noObjcOverrideConflictingOverloadsEnabled.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("objCName.kt")
|
@TestMetadata("objCName.kt")
|
||||||
public void testObjCName() throws Exception {
|
public void testObjCName() throws Exception {
|
||||||
@@ -104,6 +116,12 @@ public class LLFirReversedNativeTestGenerated extends AbstractLLFirReversedNativ
|
|||||||
runTest("compiler/testData/diagnostics/nativeTests/objCRefinement.kt");
|
runTest("compiler/testData/diagnostics/nativeTests/objCRefinement.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("objcOverrideApplicability.kt")
|
||||||
|
public void testObjcOverrideApplicability() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/nativeTests/objcOverrideApplicability.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("resolveToDelegatedProperty.kt")
|
@TestMetadata("resolveToDelegatedProperty.kt")
|
||||||
public void testResolveToDelegatedProperty() throws Exception {
|
public void testResolveToDelegatedProperty() throws Exception {
|
||||||
|
|||||||
+4
@@ -103,5 +103,9 @@ object NATIVE_DIAGNOSTICS_LIST : DiagnosticList("FirNativeErrors") {
|
|||||||
val CONSTRUCTOR_MATCHES_SEVERAL_SUPER_CONSTRUCTORS by error<KtElement>() {
|
val CONSTRUCTOR_MATCHES_SEVERAL_SUPER_CONSTRUCTORS by error<KtElement>() {
|
||||||
parameter<FqName>("annotation")
|
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_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_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 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 {
|
init {
|
||||||
RootDiagnosticRendererFactory.registerFactory(FirNativeErrorsDefaultMessages)
|
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.SYMBOL
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOLS
|
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.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_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_MATCHES_SEVERAL_SUPER_CONSTRUCTORS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors.CONSTRUCTOR_OVERRIDES_ALREADY_OVERRIDDEN_OBJC_INITIALIZER
|
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.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_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_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_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_SHARED_IMMUTABLE_TOP_LEVEL
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors.INAPPLICABLE_THREAD_LOCAL
|
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.",
|
"Constructor with ''@{0}'' matches more than one of super constructors.",
|
||||||
TO_STRING
|
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,
|
FirNativeSharedImmutableChecker,
|
||||||
FirNativeThreadLocalChecker,
|
FirNativeThreadLocalChecker,
|
||||||
FirNativeIdentifierChecker,
|
FirNativeIdentifierChecker,
|
||||||
FirNativeObjCNameChecker
|
FirNativeObjCNameChecker,
|
||||||
|
)
|
||||||
|
|
||||||
|
override val functionCheckers: Set<FirFunctionChecker>
|
||||||
|
get() = setOf(
|
||||||
|
FirNativeObjcOverrideApplicabilityChecker
|
||||||
)
|
)
|
||||||
|
|
||||||
override val callableDeclarationCheckers: Set<FirCallableDeclarationChecker>
|
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_OVERRIDES_ALREADY_OVERRIDDEN_OBJC_INITIALIZER",
|
||||||
"CONSTRUCTOR_DOES_NOT_OVERRIDE_ANY_SUPER_CONSTRUCTOR",
|
"CONSTRUCTOR_DOES_NOT_OVERRIDE_ANY_SUPER_CONSTRUCTOR",
|
||||||
"CONSTRUCTOR_MATCHES_SEVERAL_SUPER_CONSTRUCTORS",
|
"CONSTRUCTOR_MATCHES_SEVERAL_SUPER_CONSTRUCTORS",
|
||||||
|
"CONFLICTING_OBJC_OVERLOADS",
|
||||||
|
"INAPPLICABLE_OBJC_OVERRIDE",
|
||||||
"NESTED_EXTERNAL_DECLARATION",
|
"NESTED_EXTERNAL_DECLARATION",
|
||||||
"WRONG_EXTERNAL_DECLARATION",
|
"WRONG_EXTERNAL_DECLARATION",
|
||||||
"NESTED_CLASS_IN_EXTERNAL_INTERFACE",
|
"NESTED_CLASS_IN_EXTERNAL_INTERFACE",
|
||||||
|
|||||||
+47
-19
@@ -6,9 +6,13 @@
|
|||||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||||
|
|
||||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory1
|
||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.FirNameConflictsTrackerComponent
|
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.*
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
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.PACKAGE_MEMBER
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.typeAliasForConstructor
|
import org.jetbrains.kotlin.fir.scopes.impl.typeAliasForConstructor
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
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.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.SpecialNames
|
import org.jetbrains.kotlin.name.SpecialNames
|
||||||
import org.jetbrains.kotlin.utils.SmartSet
|
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) {
|
object FirConflictsDeclarationChecker : FirBasicDeclarationChecker(MppCheckerKind.Platform) {
|
||||||
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
@@ -90,21 +123,16 @@ object FirConflictsDeclarationChecker : FirBasicDeclarationChecker(MppCheckerKin
|
|||||||
conflictingDeclaration.isPrimaryConstructor && symbols.all { it.isPrimaryConstructor }
|
conflictingDeclaration.isPrimaryConstructor && symbols.all { it.isPrimaryConstructor }
|
||||||
) return@forEach
|
) return@forEach
|
||||||
|
|
||||||
when {
|
if (symbols.singleOrNull()?.let { isExpectAndActual(conflictingDeclaration, it) } == true) {
|
||||||
symbols.singleOrNull()?.let { isExpectAndActual(conflictingDeclaration, it) } == true -> {
|
reporter.reportOn(source, FirErrors.EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE, conflictingDeclaration, context)
|
||||||
reporter.reportOn(source, FirErrors.EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE, conflictingDeclaration, context)
|
return@forEach
|
||||||
}
|
}
|
||||||
conflictingDeclaration is FirNamedFunctionSymbol || conflictingDeclaration is FirConstructorSymbol -> {
|
|
||||||
reporter.reportOn(source, FirErrors.CONFLICTING_OVERLOADS, symbols, context)
|
val dispatcher = context.session.conflictDeclarationsDiagnosticDispatcher ?: PlatformConflictDeclarationsDiagnosticDispatcher.DEFAULT
|
||||||
}
|
val factory = dispatcher.getDiagnostic(conflictingDeclaration, symbols, context)
|
||||||
conflictingDeclaration is FirClassLikeSymbol<*> &&
|
|
||||||
conflictingDeclaration.getContainingClassSymbol(context.session) == null &&
|
if (factory != null) {
|
||||||
symbols.any { it is FirClassLikeSymbol<*> } -> {
|
reporter.reportOn(source, factory, symbols, context)
|
||||||
reporter.reportOn(source, FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION, symbols, context)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
reporter.reportOn(source, FirErrors.REDECLARATION, symbols, context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-3
@@ -7,23 +7,25 @@ package org.jetbrains.kotlin.fir.session
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.fir.*
|
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.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.FirNativeClassMapper
|
||||||
|
import org.jetbrains.kotlin.fir.backend.native.FirNativeOverrideChecker
|
||||||
import org.jetbrains.kotlin.fir.checkers.registerNativeCheckers
|
import org.jetbrains.kotlin.fir.checkers.registerNativeCheckers
|
||||||
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirBuiltinSyntheticFunctionInterfaceProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirBuiltinSyntheticFunctionInterfaceProvider
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
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.scopes.FirPlatformClassMapper
|
||||||
import org.jetbrains.kotlin.fir.session.FirSessionFactoryHelper.registerDefaultComponents
|
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.impl.KlibResolvedModuleDescriptorsFactoryImpl.Companion.FORWARD_DECLARATIONS_MODULE_NAME
|
||||||
import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary
|
import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
object FirNativeSessionFactory : FirAbstractSessionFactory() {
|
object FirNativeSessionFactory : FirAbstractSessionFactory() {
|
||||||
@OptIn(SessionConfiguration::class)
|
|
||||||
fun createLibrarySession(
|
fun createLibrarySession(
|
||||||
mainModuleName: Name,
|
mainModuleName: Name,
|
||||||
resolvedLibraries: List<KotlinResolvedLibrary>,
|
resolvedLibraries: List<KotlinResolvedLibrary>,
|
||||||
@@ -63,7 +65,6 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(SessionConfiguration::class)
|
|
||||||
fun createModuleBasedSession(
|
fun createModuleBasedSession(
|
||||||
moduleData: FirModuleData,
|
moduleData: FirModuleData,
|
||||||
sessionProvider: FirProjectSessionProvider,
|
sessionProvider: FirProjectSessionProvider,
|
||||||
@@ -102,5 +103,7 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
|
|||||||
fun FirSession.registerNativeComponents() {
|
fun FirSession.registerNativeComponents() {
|
||||||
register(FirPlatformClassMapper::class, FirNativeClassMapper())
|
register(FirPlatformClassMapper::class, FirNativeClassMapper())
|
||||||
register(FirPlatformSpecificCastChecker::class, FirNativeCastChecker)
|
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
|
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 {
|
decodeObjCMethodAnnotation(session)?.let {
|
||||||
return it
|
return it
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve
|
package org.jetbrains.kotlin.resolve
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.util.containers.MultiMap
|
import com.intellij.util.containers.MultiMap
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.container.DefaultImplementation
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.diagnostics.reportOnDeclaration
|
import org.jetbrains.kotlin.diagnostics.reportOnDeclaration
|
||||||
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
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 org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import java.util.*
|
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(
|
class OverloadResolver(
|
||||||
private val trace: BindingTrace,
|
private val trace: BindingTrace,
|
||||||
private val overloadFilter: OverloadFilter,
|
private val overloadFilter: OverloadFilter,
|
||||||
private val overloadChecker: OverloadChecker,
|
private val overloadChecker: OverloadChecker,
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
private val errorDispatcher: ConflictingOverloadsDispatcher,
|
||||||
|
private val languageVersionSettings: LanguageVersionSettings,
|
||||||
mainFunctionDetectorFactory: MainFunctionDetector.Factory
|
mainFunctionDetectorFactory: MainFunctionDetector.Factory
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@@ -299,12 +326,9 @@ class OverloadResolver(
|
|||||||
if (redeclarations.isEmpty()) return
|
if (redeclarations.isEmpty()) return
|
||||||
|
|
||||||
for (memberDescriptor in redeclarations) {
|
for (memberDescriptor in redeclarations) {
|
||||||
when (memberDescriptor) {
|
val diagnostic = errorDispatcher.getDiagnostic(languageVersionSettings, memberDescriptor, redeclarations) ?: continue
|
||||||
is PropertyDescriptor,
|
reportOnDeclaration(trace, memberDescriptor) {
|
||||||
is ClassifierDescriptor ->
|
diagnostic.on(it, redeclarations)
|
||||||
reportOnDeclaration(trace, memberDescriptor) { Errors.REDECLARATION.on(it, redeclarations) }
|
|
||||||
is FunctionDescriptor ->
|
|
||||||
reportOnDeclaration(trace, memberDescriptor) { Errors.CONFLICTING_OVERLOADS.on(it, redeclarations) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,28 +42,34 @@ headerFilter = lib.h
|
|||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
@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() {
|
class OverrideAll : ObjCClass() {
|
||||||
|
@ObjCSignatureOverride
|
||||||
override fun fooWithArg(arg: Int, arg2: String?) = "D"
|
override fun fooWithArg(arg: Int, arg2: String?) = "D"
|
||||||
|
@ObjCSignatureOverride
|
||||||
override fun fooWithArg(ohNoOtherName: Int, name2: String?) = "E"
|
override fun fooWithArg(ohNoOtherName: Int, name2: String?) = "E"
|
||||||
|
@ObjCSignatureOverride
|
||||||
override fun fooWithArg(arg: Int, name3: String?) = "F"
|
override fun fooWithArg(arg: Int, name3: String?) = "F"
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("CONFLICTING_OVERLOADS")
|
|
||||||
class OverrideNone : ObjCClass() {
|
class OverrideNone : ObjCClass() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("CONFLICTING_OVERLOADS")
|
|
||||||
class OverrideOne : ObjCClass() {
|
class OverrideOne : ObjCClass() {
|
||||||
override fun fooWithArg(arg: Int, arg2: String?) = "G"
|
override fun fooWithArg(arg: Int, arg2: String?) = "G"
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("CONFLICTING_OVERLOADS")
|
|
||||||
class OverrideWithDifferentFirstArgName : ObjCClass() {
|
class OverrideWithDifferentFirstArgName : ObjCClass() {
|
||||||
|
@ObjCSignatureOverride
|
||||||
override fun fooWithArg(a: Int, arg2: String?) = "H"
|
override fun fooWithArg(a: Int, arg2: String?) = "H"
|
||||||
|
@ObjCSignatureOverride
|
||||||
override fun fooWithArg(b: Int, name2: String?) = "I"
|
override fun fooWithArg(b: Int, name2: String?) = "I"
|
||||||
|
@ObjCSignatureOverride
|
||||||
override fun fooWithArg(c: Int, name3: String?) = "J"
|
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
|
DisableCompatibilityModeForNewInference(KOTLIN_2_0, kind = OTHER), // KT-63558 (umbrella), KT-64306, KT-64307, KT-64308
|
||||||
DfaBooleanVariables(KOTLIN_2_0), // KT-25747
|
DfaBooleanVariables(KOTLIN_2_0), // KT-25747
|
||||||
LightweightLambdas(KOTLIN_2_0, kind = OTHER), // KT-45375
|
LightweightLambdas(KOTLIN_2_0, kind = OTHER), // KT-45375
|
||||||
|
ObjCSignatureOverrideAnnotation(KOTLIN_2_0, sinceApiVersion = ApiVersion.KOTLIN_2_0, kind = OTHER), // KT-61323
|
||||||
|
|
||||||
// 2.1
|
// 2.1
|
||||||
|
|
||||||
|
|||||||
+3
@@ -25,6 +25,9 @@ object NativeStandardInteropNames {
|
|||||||
val objCOutletClassId = ClassId(cInteropPackage, Name.identifier("ObjCOutlet"))
|
val objCOutletClassId = ClassId(cInteropPackage, Name.identifier("ObjCOutlet"))
|
||||||
val objCOverrideInitClassId = ClassId(cInteropPackage, Name.identifier("ObjCObjectBase.OverrideInit"))
|
val objCOverrideInitClassId = ClassId(cInteropPackage, Name.identifier("ObjCObjectBase.OverrideInit"))
|
||||||
|
|
||||||
|
object Annotations {
|
||||||
|
val objCSignatureOverrideClassId = ClassId(cInteropPackage, Name.identifier("ObjCSignatureOverride"))
|
||||||
|
}
|
||||||
|
|
||||||
object ForwardDeclarations {
|
object ForwardDeclarations {
|
||||||
private val cNamesPackage = FqName("cnames")
|
private val cNamesPackage = FqName("cnames")
|
||||||
|
|||||||
@@ -63,3 +63,21 @@ public annotation class BetaInteropApi
|
|||||||
@Retention(AnnotationRetention.BINARY)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
|
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
|
||||||
public annotation class ExperimentalForeignApi
|
public annotation class ExperimentalForeignApi
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks functions for which Objective-C rules should be used for determinating whether two functions are conflicting.
|
||||||
|
*
|
||||||
|
* Objective-C allows overloads by selector. Such functions can have same types, and differ only by parameter names in Kotlin,
|
||||||
|
* while it is not generally supported.
|
||||||
|
*
|
||||||
|
* This leads to an error, when a Kotlin class attempts to override both versions of a method that is overloaded by names only.
|
||||||
|
*
|
||||||
|
* If all such methods are annotated by this annotation, the error would be suppressed.
|
||||||
|
*
|
||||||
|
* Annotation is only applicable to overrides of methods coming from Objective-C interop.
|
||||||
|
*/
|
||||||
|
@Target(AnnotationTarget.FUNCTION)
|
||||||
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
|
@Suppress("NEWER_VERSION_IN_SINCE_KOTLIN")
|
||||||
|
@SinceKotlin("2.0")
|
||||||
|
public annotation class ObjCSignatureOverride
|
||||||
-3
@@ -68,9 +68,6 @@ internal inline fun <F> PhaseContext.firFrontend(
|
|||||||
metadataCompilationMode = config.metadataKlib,
|
metadataCompilationMode = config.metadataKlib,
|
||||||
isCommonSource = isCommonSource,
|
isCommonSource = isCommonSource,
|
||||||
fileBelongsToModule = fileBelongsToModule,
|
fileBelongsToModule = fileBelongsToModule,
|
||||||
registerExtraComponents = {
|
|
||||||
it.register(FirOverrideChecker::class, FirNativeOverrideChecker(it))
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val outputs = sessionsWithSources.map { (session, sources) ->
|
val outputs = sessionsWithSources.map { (session, sources) ->
|
||||||
|
|||||||
+9
@@ -90,6 +90,15 @@ private val DIAGNOSTIC_FACTORY_TO_RENDERER by lazy {
|
|||||||
"Can't refer to forward declaration ''{0}'' from class literal",
|
"Can't refer to forward declaration ''{0}'' from class literal",
|
||||||
Renderers.RENDER_TYPE
|
Renderers.RENDER_TYPE
|
||||||
)
|
)
|
||||||
|
put(
|
||||||
|
ErrorsNative.CONFLICTING_OBJC_OVERLOADS,
|
||||||
|
"Conflicting overloads: {0}. Add @ObjCSignatureOverride to allow collision for functions inherited from Objective-C.",
|
||||||
|
CommonRenderers.commaSeparated(Renderers.FQ_NAMES_IN_TYPES)
|
||||||
|
)
|
||||||
|
put(
|
||||||
|
ErrorsNative.INAPPLICABLE_OBJC_OVERRIDE,
|
||||||
|
"@ObjCSignatureOverride is only allowed on functions inherited from Objective-C.",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,10 @@ object ErrorsNative {
|
|||||||
val FORWARD_DECLARATION_AS_REIFIED_TYPE_ARGUMENT = DiagnosticFactory1.create<PsiElement, KotlinType>(Severity.ERROR)
|
val FORWARD_DECLARATION_AS_REIFIED_TYPE_ARGUMENT = DiagnosticFactory1.create<PsiElement, KotlinType>(Severity.ERROR)
|
||||||
@JvmField
|
@JvmField
|
||||||
val FORWARD_DECLARATION_AS_CLASS_LITERAL = DiagnosticFactory1.create<PsiElement, KotlinType>(Severity.ERROR)
|
val FORWARD_DECLARATION_AS_CLASS_LITERAL = DiagnosticFactory1.create<PsiElement, KotlinType>(Severity.ERROR)
|
||||||
|
@JvmField
|
||||||
|
val CONFLICTING_OBJC_OVERLOADS = DiagnosticFactory1.create<PsiElement, Collection<DeclarationDescriptor>>(Severity.ERROR)
|
||||||
|
@JvmField
|
||||||
|
val INAPPLICABLE_OBJC_OVERRIDE = DiagnosticFactory0.create<PsiElement>(Severity.ERROR)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
Errors.Initializer.initializeFactoryNames(ErrorsNative::class.java)
|
Errors.Initializer.initializeFactoryNames(ErrorsNative::class.java)
|
||||||
|
|||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* 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.resolve.konan.diagnostics
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1
|
||||||
|
import org.jetbrains.kotlin.ir.objcinterop.getObjCMethodInfo
|
||||||
|
import org.jetbrains.kotlin.name.NativeStandardInteropNames.Annotations.objCSignatureOverrideClassId
|
||||||
|
import org.jetbrains.kotlin.resolve.ConflictingOverloadsDispatcher
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 FunctionDescriptor.hasDifferentParameterNames(other: FunctionDescriptor) : Boolean {
|
||||||
|
return valueParameters.drop(1).map { it.name } != other.valueParameters.drop(1).map { it.name }
|
||||||
|
}
|
||||||
|
|
||||||
|
object NativeConflictingOverloadsDispatcher : ConflictingOverloadsDispatcher {
|
||||||
|
override fun getDiagnostic(
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
|
declaration: DeclarationDescriptor,
|
||||||
|
redeclarations: Collection<DeclarationDescriptor>
|
||||||
|
): DiagnosticFactory1<PsiElement, Collection<DeclarationDescriptor>>? {
|
||||||
|
if (languageVersionSettings.supportsFeature(LanguageFeature.ObjCSignatureOverrideAnnotation)) {
|
||||||
|
if (declaration is FunctionDescriptor && redeclarations.all { it is FunctionDescriptor }) {
|
||||||
|
if (declaration.getObjCMethodInfo() != null && redeclarations.all { (it as FunctionDescriptor).getObjCMethodInfo() != null }) {
|
||||||
|
if (redeclarations.all { it === declaration || (it as FunctionDescriptor).hasDifferentParameterNames(declaration) }) {
|
||||||
|
if (declaration.annotations.hasAnnotation(objCSignatureOverrideClassId.asSingleFqName())) {
|
||||||
|
return null
|
||||||
|
} else {
|
||||||
|
return ErrorsNative.CONFLICTING_OBJC_OVERLOADS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ConflictingOverloadsDispatcher.Default.getDiagnostic(languageVersionSettings, declaration, redeclarations)
|
||||||
|
}
|
||||||
|
}
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* 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.resolve.konan.diagnostics
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.objcinterop.getObjCMethodInfo
|
||||||
|
import org.jetbrains.kotlin.name.NativeStandardInteropNames.Annotations.objCSignatureOverrideClassId
|
||||||
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||||
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||||
|
|
||||||
|
|
||||||
|
object NativeObjcOverrideApplicabilityChecker : DeclarationChecker {
|
||||||
|
override fun check(
|
||||||
|
declaration: KtDeclaration,
|
||||||
|
descriptor: DeclarationDescriptor,
|
||||||
|
context: DeclarationCheckerContext,
|
||||||
|
) {
|
||||||
|
if (descriptor is FunctionDescriptor) {
|
||||||
|
val annotation = descriptor.annotations.findAnnotation(objCSignatureOverrideClassId.asSingleFqName()) ?: return
|
||||||
|
if (descriptor.getObjCMethodInfo() == null) {
|
||||||
|
context.trace.report(ErrorsNative.INAPPLICABLE_OBJC_OVERRIDE.on(DescriptorToSourceUtils.getSourceFromAnnotation(annotation) ?: declaration))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -30,6 +30,7 @@ object NativePlatformConfigurator : PlatformConfiguratorBase(
|
|||||||
NativeObjCNameChecker, NativeObjCNameOverridesChecker,
|
NativeObjCNameChecker, NativeObjCNameOverridesChecker,
|
||||||
NativeObjCRefinementChecker, NativeObjCRefinementAnnotationChecker,
|
NativeObjCRefinementChecker, NativeObjCRefinementAnnotationChecker,
|
||||||
NativeObjCRefinementOverridesChecker, NativeHiddenFromObjCInheritanceChecker,
|
NativeObjCRefinementOverridesChecker, NativeHiddenFromObjCInheritanceChecker,
|
||||||
|
NativeObjcOverrideApplicabilityChecker,
|
||||||
),
|
),
|
||||||
platformSpecificCastChecker = NativePlatformSpecificCastChecker
|
platformSpecificCastChecker = NativePlatformSpecificCastChecker
|
||||||
) {
|
) {
|
||||||
@@ -37,6 +38,7 @@ object NativePlatformConfigurator : PlatformConfiguratorBase(
|
|||||||
container.useInstance(NativeInliningRule)
|
container.useInstance(NativeInliningRule)
|
||||||
container.useImpl<NativeIdentifierChecker>()
|
container.useImpl<NativeIdentifierChecker>()
|
||||||
container.useImpl<NativeForwardDeclarationRttiChecker>()
|
container.useImpl<NativeForwardDeclarationRttiChecker>()
|
||||||
|
container.useInstance(NativeConflictingOverloadsDispatcher)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun configureModuleDependentCheckers(container: StorageComponentContainer) {
|
override fun configureModuleDependentCheckers(container: StorageComponentContainer) {
|
||||||
|
|||||||
+1
-1
@@ -119,7 +119,7 @@ class Bar : Foo() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("CONFLICTING_OVERLOADS")
|
@Suppress("CONFLICTING_OBJC_OVERLOADS")
|
||||||
class MutablePairImpl(first: Int, second: Int) : NSObject(), MutablePairProtocol {
|
class MutablePairImpl(first: Int, second: Int) : NSObject(), MutablePairProtocol {
|
||||||
private var elements = intArrayOf(first, second)
|
private var elements = intArrayOf(first, second)
|
||||||
|
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ class Bar : Foo() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("CONFLICTING_OVERLOADS")
|
@Suppress("CONFLICTING_OBJC_OVERLOADS")
|
||||||
class MutablePairImpl(first: Int, second: Int) : NSObject(), MutablePairProtocol {
|
class MutablePairImpl(first: Int, second: Int) : NSObject(), MutablePairProtocol {
|
||||||
private var elements = intArrayOf(first, second)
|
private var elements = intArrayOf(first, second)
|
||||||
|
|
||||||
|
|||||||
+18
@@ -66,6 +66,18 @@ public class DiagnosticsNativeTestGenerated extends AbstractDiagnosticsNativeTes
|
|||||||
runTest("compiler/testData/diagnostics/nativeTests/nativeProtectedFunCall.kt");
|
runTest("compiler/testData/diagnostics/nativeTests/nativeProtectedFunCall.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("noObjcOverrideConflictingOverloadsDisabled.kt")
|
||||||
|
public void testNoObjcOverrideConflictingOverloadsDisabled() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/nativeTests/noObjcOverrideConflictingOverloadsDisabled.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("noObjcOverrideConflictingOverloadsEnabled.kt")
|
||||||
|
public void testNoObjcOverrideConflictingOverloadsEnabled() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/nativeTests/noObjcOverrideConflictingOverloadsEnabled.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("objCName.kt")
|
@TestMetadata("objCName.kt")
|
||||||
public void testObjCName() throws Exception {
|
public void testObjCName() throws Exception {
|
||||||
@@ -102,6 +114,12 @@ public class DiagnosticsNativeTestGenerated extends AbstractDiagnosticsNativeTes
|
|||||||
runTest("compiler/testData/diagnostics/nativeTests/objCRefinement.kt");
|
runTest("compiler/testData/diagnostics/nativeTests/objCRefinement.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("objcOverrideApplicability.kt")
|
||||||
|
public void testObjcOverrideApplicability() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/nativeTests/objcOverrideApplicability.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("resolveToDelegatedProperty.kt")
|
@TestMetadata("resolveToDelegatedProperty.kt")
|
||||||
public void testResolveToDelegatedProperty() throws Exception {
|
public void testResolveToDelegatedProperty() throws Exception {
|
||||||
|
|||||||
+18
@@ -70,6 +70,18 @@ public class FirLightTreeOldFrontendNativeDiagnosticsTestGenerated extends Abstr
|
|||||||
runTest("compiler/testData/diagnostics/nativeTests/nativeProtectedFunCall.kt");
|
runTest("compiler/testData/diagnostics/nativeTests/nativeProtectedFunCall.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("noObjcOverrideConflictingOverloadsDisabled.kt")
|
||||||
|
public void testNoObjcOverrideConflictingOverloadsDisabled() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/nativeTests/noObjcOverrideConflictingOverloadsDisabled.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("noObjcOverrideConflictingOverloadsEnabled.kt")
|
||||||
|
public void testNoObjcOverrideConflictingOverloadsEnabled() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/nativeTests/noObjcOverrideConflictingOverloadsEnabled.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("objCName.kt")
|
@TestMetadata("objCName.kt")
|
||||||
public void testObjCName() throws Exception {
|
public void testObjCName() throws Exception {
|
||||||
@@ -106,6 +118,12 @@ public class FirLightTreeOldFrontendNativeDiagnosticsTestGenerated extends Abstr
|
|||||||
runTest("compiler/testData/diagnostics/nativeTests/objCRefinement.kt");
|
runTest("compiler/testData/diagnostics/nativeTests/objCRefinement.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("objcOverrideApplicability.kt")
|
||||||
|
public void testObjcOverrideApplicability() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/nativeTests/objcOverrideApplicability.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("resolveToDelegatedProperty.kt")
|
@TestMetadata("resolveToDelegatedProperty.kt")
|
||||||
public void testResolveToDelegatedProperty() throws Exception {
|
public void testResolveToDelegatedProperty() throws Exception {
|
||||||
|
|||||||
+18
@@ -70,6 +70,18 @@ public class FirPsiOldFrontendNativeDiagnosticsTestGenerated extends AbstractFir
|
|||||||
runTest("compiler/testData/diagnostics/nativeTests/nativeProtectedFunCall.kt");
|
runTest("compiler/testData/diagnostics/nativeTests/nativeProtectedFunCall.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("noObjcOverrideConflictingOverloadsDisabled.kt")
|
||||||
|
public void testNoObjcOverrideConflictingOverloadsDisabled() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/nativeTests/noObjcOverrideConflictingOverloadsDisabled.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("noObjcOverrideConflictingOverloadsEnabled.kt")
|
||||||
|
public void testNoObjcOverrideConflictingOverloadsEnabled() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/nativeTests/noObjcOverrideConflictingOverloadsEnabled.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("objCName.kt")
|
@TestMetadata("objCName.kt")
|
||||||
public void testObjCName() throws Exception {
|
public void testObjCName() throws Exception {
|
||||||
@@ -106,6 +118,12 @@ public class FirPsiOldFrontendNativeDiagnosticsTestGenerated extends AbstractFir
|
|||||||
runTest("compiler/testData/diagnostics/nativeTests/objCRefinement.kt");
|
runTest("compiler/testData/diagnostics/nativeTests/objCRefinement.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("objcOverrideApplicability.kt")
|
||||||
|
public void testObjcOverrideApplicability() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/nativeTests/objcOverrideApplicability.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("resolveToDelegatedProperty.kt")
|
@TestMetadata("resolveToDelegatedProperty.kt")
|
||||||
public void testResolveToDelegatedProperty() throws Exception {
|
public void testResolveToDelegatedProperty() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user