[FIR] Fix ambiguity of Throws and other std annotations importing
Including `SharedImmutable` and `ThreadLocal` Simplify code, remove `DefaultImportPriority.KOTLIN_THROWS` Introduce `FirNativeClassMapper`
This commit is contained in:
committed by
Space Team
parent
adf4f823ae
commit
115d685d91
@@ -7,6 +7,7 @@ dependencies {
|
||||
api(project(":core:descriptors.jvm"))
|
||||
api(project(":compiler:frontend.java"))
|
||||
api(project(":compiler:fir:java"))
|
||||
api(project(":compiler:fir:native"))
|
||||
api(project(":compiler:fir:raw-fir:psi2fir"))
|
||||
api(project(":compiler:fir:raw-fir:light-tree2fir"))
|
||||
api(project(":compiler:fir:fir2ir"))
|
||||
|
||||
+7
@@ -9,12 +9,15 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.BinaryModuleData
|
||||
import org.jetbrains.kotlin.fir.FirModuleData
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.SessionConfiguration
|
||||
import org.jetbrains.kotlin.fir.backend.native.FirNativeClassMapper
|
||||
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.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
|
||||
@@ -22,6 +25,7 @@ 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>,
|
||||
@@ -39,6 +43,7 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
|
||||
extensionRegistrars,
|
||||
registerExtraComponents = { session ->
|
||||
session.registerDefaultComponents()
|
||||
session.register(FirPlatformClassMapper::class, FirNativeClassMapper())
|
||||
registerExtraComponents(session)
|
||||
},
|
||||
createKotlinScopeProvider = { FirKotlinScopeProvider() },
|
||||
@@ -64,6 +69,7 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
|
||||
})
|
||||
}
|
||||
|
||||
@OptIn(SessionConfiguration::class)
|
||||
fun createModuleBasedSession(
|
||||
moduleData: FirModuleData,
|
||||
sessionProvider: FirProjectSessionProvider,
|
||||
@@ -83,6 +89,7 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
|
||||
init,
|
||||
registerExtraComponents = {
|
||||
it.registerDefaultComponents()
|
||||
it.register(FirPlatformClassMapper::class, FirNativeClassMapper())
|
||||
registerExtraComponents(it)
|
||||
},
|
||||
registerExtraCheckers = { it.registerNativeCheckers() },
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.FirPlatformClassMapper
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.JvmStandardClassIds
|
||||
|
||||
@NoMutableState
|
||||
class FirJavaClassMapper(private val session: FirSession) : FirPlatformClassMapper() {
|
||||
@@ -30,4 +31,8 @@ class FirJavaClassMapper(private val session: FirSession) : FirPlatformClassMapp
|
||||
if (classId == null) return null
|
||||
return JavaToKotlinClassMap.mapJavaToKotlin(classId.asSingleFqName())
|
||||
}
|
||||
|
||||
override val classTypealiasesThatDontCauseAmbiguity: Map<ClassId, ClassId> = mapOf(
|
||||
JvmStandardClassIds.Annotations.Throws to JvmStandardClassIds.Annotations.ThrowsAlias,
|
||||
)
|
||||
}
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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.backend.native
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.scopes.FirPlatformClassMapper
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.NativeRuntimeNames
|
||||
|
||||
class FirNativeClassMapper : FirPlatformClassMapper() {
|
||||
override fun getCorrespondingPlatformClass(declaration: FirClassLikeDeclaration): FirRegularClass? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getCorrespondingPlatformClass(classId: ClassId?): ClassId? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getCorrespondingKotlinClass(classId: ClassId?): ClassId? {
|
||||
return null
|
||||
}
|
||||
|
||||
override val classTypealiasesThatDontCauseAmbiguity: Map<ClassId, ClassId> = mapOf(
|
||||
NativeRuntimeNames.Annotations.Throws to NativeRuntimeNames.Annotations.ThrowsAlias,
|
||||
NativeRuntimeNames.Annotations.SharedImmutable to NativeRuntimeNames.Annotations.SharedImmutableAlias,
|
||||
NativeRuntimeNames.Annotations.ThreadLocal to NativeRuntimeNames.Annotations.ThreadLocalAlias
|
||||
)
|
||||
}
|
||||
@@ -26,6 +26,8 @@ abstract class FirPlatformClassMapper : FirSessionComponent {
|
||||
override fun getCorrespondingKotlinClass(classId: ClassId?): ClassId? {
|
||||
return null
|
||||
}
|
||||
|
||||
override val classTypealiasesThatDontCauseAmbiguity: Map<ClassId, ClassId> = emptyMap()
|
||||
}
|
||||
|
||||
abstract fun getCorrespondingPlatformClass(declaration: FirClassLikeDeclaration): FirRegularClass?
|
||||
@@ -33,6 +35,12 @@ abstract class FirPlatformClassMapper : FirSessionComponent {
|
||||
abstract fun getCorrespondingPlatformClass(classId: ClassId?): ClassId?
|
||||
|
||||
abstract fun getCorrespondingKotlinClass(classId: ClassId?): ClassId?
|
||||
|
||||
// Compiler should not report ambiguity for certain platform classes and their type aliases
|
||||
// For instance, there is no ambiguity between `kotlin.Throws` and `kotlin.jvm.Throws`
|
||||
// To achieve this goal, `FirTypeResolver` uses this map and tries to find candidates with identifiers from the map's keys
|
||||
// And remove corresponding type aliases (value of map) if they are presented in the candidate set
|
||||
abstract val classTypealiasesThatDontCauseAmbiguity: Map<ClassId, ClassId>
|
||||
}
|
||||
|
||||
val FirSession.platformClassMapper: FirPlatformClassMapper by FirSession.sessionComponentAccessor()
|
||||
|
||||
-8
@@ -25,14 +25,6 @@ enum class DefaultImportPriority {
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
): List<ImportPath>? =
|
||||
platformDependentAnalyzerServices?.defaultLowPriorityImports
|
||||
},
|
||||
KOTLIN_THROWS {
|
||||
override fun getAllDefaultImports(
|
||||
platformDependentAnalyzerServices: PlatformDependentAnalyzerServices?,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
): List<ImportPath> {
|
||||
return listOf(ImportPath.fromString("kotlin.Throws"))
|
||||
}
|
||||
};
|
||||
|
||||
abstract fun getAllDefaultImports(
|
||||
|
||||
+21
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.ResolutionDiagnostic
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ScopeClassDeclaration
|
||||
import org.jetbrains.kotlin.fir.scopes.platformClassMapper
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
@@ -134,6 +135,8 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
||||
}
|
||||
}
|
||||
|
||||
filterOutAmbiguousTypealiases(candidates)
|
||||
|
||||
val candidateCount = candidates.size
|
||||
return when {
|
||||
candidateCount == 1 -> {
|
||||
@@ -150,6 +153,24 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun filterOutAmbiguousTypealiases(candidates: MutableSet<TypeCandidate>) {
|
||||
if (candidates.size <= 1) return
|
||||
|
||||
val aliasesToRemove = mutableSetOf<ClassId>()
|
||||
val classTypealiasesThatDontCauseAmbiguity = session.platformClassMapper.classTypealiasesThatDontCauseAmbiguity
|
||||
for (candidate in candidates) {
|
||||
val symbol = candidate.symbol
|
||||
if (symbol is FirClassLikeSymbol<*>) {
|
||||
classTypealiasesThatDontCauseAmbiguity[symbol.classId]?.let { aliasesToRemove.add(it) }
|
||||
}
|
||||
}
|
||||
if (aliasesToRemove.isNotEmpty()) {
|
||||
candidates.removeAll {
|
||||
(it.symbol as? FirClassLikeSymbol)?.classId?.let { classId -> aliasesToRemove.contains(classId) } == true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class TypeResolutionResult {
|
||||
class Ambiguity(val typeCandidates: List<TypeCandidate>) : TypeResolutionResult()
|
||||
object Unresolved : TypeResolutionResult()
|
||||
|
||||
@@ -70,10 +70,6 @@ internal fun computeImportingScopes(
|
||||
FirSingleLevelDefaultStarImportingScope(session, scopeSession, DefaultImportPriority.LOW, excludedImportNames)
|
||||
},
|
||||
)
|
||||
|
||||
this += scopeSession.getOrBuild(DefaultSimpleImportKey(DefaultImportPriority.KOTLIN_THROWS, excludedImportNames), DEFAULT_SIMPLE_IMPORT) {
|
||||
FirDefaultSimpleImportingScope(session, scopeSession, priority = DefaultImportPriority.KOTLIN_THROWS, excludedImportNames)
|
||||
}
|
||||
}
|
||||
|
||||
this += FirExplicitStarImportingScope(file.imports, session, scopeSession, excludedImportNames)
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import kotlin.*
|
||||
import kotlin.jvm.*
|
||||
import kotlin.native.concurrent.*
|
||||
import kotlin.native.*
|
||||
|
||||
@<!DEPRECATION!>SharedImmutable<!>
|
||||
@ThreadLocal
|
||||
val x = 42
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun test() {}
|
||||
@@ -0,0 +1,11 @@
|
||||
import kotlin.*
|
||||
import kotlin.jvm.*
|
||||
import kotlin.native.concurrent.*
|
||||
import kotlin.native.*
|
||||
|
||||
@<!DEPRECATION, TYPEALIAS_EXPANSION_DEPRECATION!>SharedImmutable<!>
|
||||
@<!DEPRECATION!>ThreadLocal<!>
|
||||
val x = 42
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun test() {}
|
||||
@@ -72,7 +72,7 @@ package abc4
|
||||
import kotlin.<!CONFLICTING_IMPORT!>Throws<!>
|
||||
import <!DEPRECATION!>kotlin.native.<!CONFLICTING_IMPORT!>Throws<!><!>
|
||||
|
||||
@<!OVERLOAD_RESOLUTION_AMBIGUITY!>Throws<!>(Throwable::class)
|
||||
@Throws(Throwable::class)
|
||||
fun foo1() {}
|
||||
|
||||
@kotlin.Throws(Throwable::class)
|
||||
@@ -81,7 +81,7 @@ fun foo2() {}
|
||||
@<!DEPRECATION!>kotlin.native.Throws<!>(Throwable::class)
|
||||
fun foo3() {}
|
||||
|
||||
fun foo5(x: <!OVERLOAD_RESOLUTION_AMBIGUITY!>Throws<!>) {}
|
||||
fun foo5(x: Throws) {}
|
||||
fun foo6(x: kotlin.Throws) {}
|
||||
fun foo7(x: <!DEPRECATION!>kotlin.native.Throws<!>) {}
|
||||
|
||||
@@ -127,7 +127,7 @@ package abc7
|
||||
import kotlin.*
|
||||
import kotlin.native.*
|
||||
|
||||
@<!OVERLOAD_RESOLUTION_AMBIGUITY!>Throws<!>(Throwable::class)
|
||||
@Throws(Throwable::class)
|
||||
fun foo1() {}
|
||||
|
||||
@kotlin.Throws(Throwable::class)
|
||||
@@ -136,7 +136,7 @@ fun foo2() {}
|
||||
@<!DEPRECATION!>kotlin.native.Throws<!>(Throwable::class)
|
||||
fun foo3() {}
|
||||
|
||||
fun foo5(x: <!OVERLOAD_RESOLUTION_AMBIGUITY!>Throws<!>) {}
|
||||
fun foo5(x: Throws) {}
|
||||
fun foo6(x: kotlin.Throws) {}
|
||||
fun foo7(x: <!DEPRECATION!>kotlin.native.Throws<!>) {}
|
||||
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// FILE: main1.kt
|
||||
package abc1
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun foo1() {}
|
||||
|
||||
@kotlin.Throws(Exception::class)
|
||||
fun foo2() {}
|
||||
|
||||
@kotlin.jvm.Throws(Exception::class)
|
||||
fun foo3() {}
|
||||
|
||||
fun foo5(x: Throws) {}
|
||||
fun foo6(x: kotlin.Throws) {}
|
||||
fun foo7(x: kotlin.jvm.Throws) {}
|
||||
|
||||
// FILE: main2.kt
|
||||
package abc2
|
||||
|
||||
import kotlin.jvm.Throws
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun foo1() {}
|
||||
|
||||
@kotlin.Throws(Exception::class)
|
||||
fun foo2() {}
|
||||
|
||||
@kotlin.jvm.Throws(Exception::class)
|
||||
fun foo3() {}
|
||||
|
||||
fun foo5(x: Throws) {}
|
||||
fun foo6(x: kotlin.Throws) {}
|
||||
fun foo7(x: kotlin.jvm.Throws) {}
|
||||
|
||||
// FILE: main3.kt
|
||||
package abc3
|
||||
|
||||
import kotlin.Throws
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun foo1() {}
|
||||
|
||||
@kotlin.Throws(Exception::class)
|
||||
fun foo2() {}
|
||||
|
||||
@kotlin.jvm.Throws(Exception::class)
|
||||
fun foo3() {}
|
||||
|
||||
fun foo5(x: Throws) {}
|
||||
fun foo6(x: kotlin.Throws) {}
|
||||
fun foo7(x: kotlin.jvm.Throws) {}
|
||||
|
||||
// FILE: main4.kt
|
||||
package abc4
|
||||
|
||||
import kotlin.<!CONFLICTING_IMPORT!>Throws<!>
|
||||
import kotlin.jvm.<!CONFLICTING_IMPORT!>Throws<!>
|
||||
|
||||
@<!OVERLOAD_RESOLUTION_AMBIGUITY!>Throws<!>(Exception::class)
|
||||
fun foo1() {}
|
||||
|
||||
@kotlin.Throws(Exception::class)
|
||||
fun foo2() {}
|
||||
|
||||
@kotlin.jvm.Throws(Exception::class)
|
||||
fun foo3() {}
|
||||
|
||||
fun foo5(x: <!OVERLOAD_RESOLUTION_AMBIGUITY!>Throws<!>) {}
|
||||
fun foo6(x: kotlin.Throws) {}
|
||||
fun foo7(x: kotlin.jvm.Throws) {}
|
||||
|
||||
// FILE: main5.kt
|
||||
package abc5
|
||||
|
||||
import kotlin.jvm.*
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun foo1() {}
|
||||
|
||||
@kotlin.Throws(Exception::class)
|
||||
fun foo2() {}
|
||||
|
||||
@kotlin.jvm.Throws(Exception::class)
|
||||
fun foo3() {}
|
||||
|
||||
fun foo5(x: Throws) {}
|
||||
fun foo6(x: kotlin.Throws) {}
|
||||
fun foo7(x: kotlin.jvm.Throws) {}
|
||||
|
||||
// FILE: main6.kt
|
||||
package abc6
|
||||
|
||||
import kotlin.*
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun foo1() {}
|
||||
|
||||
@kotlin.Throws(Exception::class)
|
||||
fun foo2() {}
|
||||
|
||||
@kotlin.jvm.Throws(Exception::class)
|
||||
fun foo3() {}
|
||||
|
||||
fun foo5(x: Throws) {}
|
||||
fun foo6(x: kotlin.Throws) {}
|
||||
fun foo7(x: kotlin.jvm.Throws) {}
|
||||
|
||||
// FILE: main7.kt
|
||||
package abc7
|
||||
|
||||
import kotlin.*
|
||||
import kotlin.jvm.*
|
||||
|
||||
@<!OVERLOAD_RESOLUTION_AMBIGUITY!>Throws<!>(Exception::class)
|
||||
fun foo1() {}
|
||||
|
||||
@kotlin.Throws(Exception::class)
|
||||
fun foo2() {}
|
||||
|
||||
@kotlin.jvm.Throws(Exception::class)
|
||||
fun foo3() {}
|
||||
|
||||
fun foo5(x: <!OVERLOAD_RESOLUTION_AMBIGUITY!>Throws<!>) {}
|
||||
fun foo6(x: kotlin.Throws) {}
|
||||
fun foo7(x: kotlin.jvm.Throws) {}
|
||||
|
||||
// FILE: main8.kt
|
||||
package abc8
|
||||
|
||||
import kotlin.*
|
||||
import kotlin.jvm.Throws
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun foo1() {}
|
||||
|
||||
@kotlin.Throws(Exception::class)
|
||||
fun foo2() {}
|
||||
|
||||
@kotlin.jvm.Throws(Exception::class)
|
||||
fun foo3() {}
|
||||
|
||||
fun foo5(x: Throws) {}
|
||||
fun foo6(x: kotlin.Throws) {}
|
||||
fun foo7(x: kotlin.jvm.Throws) {}
|
||||
|
||||
// FILE: main9.kt
|
||||
package abc9
|
||||
|
||||
import kotlin.jvm.*
|
||||
import kotlin.Throws
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun foo1() {}
|
||||
|
||||
@kotlin.Throws(Exception::class)
|
||||
fun foo2() {}
|
||||
|
||||
@kotlin.jvm.Throws(Exception::class)
|
||||
fun foo3() {}
|
||||
|
||||
fun foo5(x: Throws) {}
|
||||
fun foo6(x: kotlin.Throws) {}
|
||||
fun foo7(x: kotlin.jvm.Throws) {}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// FILE: main1.kt
|
||||
package abc1
|
||||
|
||||
Reference in New Issue
Block a user