K2: introduce platform-dependent filtering for non-JVM platforms
This commit fixes a false negative in testData/cli/metadata/getOrDefault Related to KT-57268
This commit is contained in:
committed by
Space Team
parent
7599ff0ef1
commit
ed246d372b
+2
-10
@@ -5,20 +5,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.scopes.jvm
|
package org.jetbrains.kotlin.fir.scopes.jvm
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.hasAnnotation
|
import org.jetbrains.kotlin.fir.scopes.FirPlatformDeclarationFilter
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
|
|
||||||
internal object FirJvmPlatformDeclarationFilter {
|
internal object FirJvmPlatformDeclarationFilter {
|
||||||
fun isFunctionAvailable(function: FirSimpleFunction, javaClassScope: FirTypeScope, session: FirSession): Boolean {
|
fun isFunctionAvailable(function: FirSimpleFunction, javaClassScope: FirTypeScope, session: FirSession): Boolean {
|
||||||
// Optimization: only run the below logic for functions named "getOrDefault" and "remove", since only two functions with these names
|
if (FirPlatformDeclarationFilter.isFunctionAvailable(function, session)) return true
|
||||||
// in kotlin.collections.Map are currently annotated with @PlatformDependent.
|
|
||||||
if (function.name !in namesToCheck) return true
|
|
||||||
|
|
||||||
if (!function.hasAnnotation(StandardNames.FqNames.platformDependentClassId, session)) return true
|
|
||||||
|
|
||||||
var isFunctionPresentInJavaAnalogue = false
|
var isFunctionPresentInJavaAnalogue = false
|
||||||
val jvmDescriptorOfKotlinFunction = function.computeJvmDescriptor()
|
val jvmDescriptorOfKotlinFunction = function.computeJvmDescriptor()
|
||||||
@@ -29,6 +23,4 @@ internal object FirJvmPlatformDeclarationFilter {
|
|||||||
}
|
}
|
||||||
return isFunctionPresentInJavaAnalogue
|
return isFunctionPresentInJavaAnalogue
|
||||||
}
|
}
|
||||||
|
|
||||||
private val namesToCheck = listOf("getOrDefault", "remove").map(Name::identifier)
|
|
||||||
}
|
}
|
||||||
|
|||||||
+55
-1
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.scopes
|
package org.jetbrains.kotlin.fir.scopes
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||||
@@ -12,6 +13,8 @@ import org.jetbrains.kotlin.fir.declarations.FirClass
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.hasAnnotation
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.delegateFields
|
import org.jetbrains.kotlin.fir.declarations.utils.delegateFields
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isData
|
import org.jetbrains.kotlin.fir.declarations.utils.isData
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
||||||
@@ -23,9 +26,14 @@ import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
|||||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhaseWithCallableMembers
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhaseWithCallableMembers
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
class FirKotlinScopeProvider(
|
class FirKotlinScopeProvider(
|
||||||
val declaredMemberScopeDecorator: (
|
val declaredMemberScopeDecorator: (
|
||||||
@@ -34,7 +42,9 @@ class FirKotlinScopeProvider(
|
|||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
memberRequiredPhase: FirResolvePhase?,
|
memberRequiredPhase: FirResolvePhase?,
|
||||||
) -> FirContainingNamesAwareScope = { _, declaredMemberScope, _, _, _ -> declaredMemberScope }
|
) -> FirContainingNamesAwareScope = { _, declaredMemberScope, session, _, _ ->
|
||||||
|
PlatformDependentFilteringScope(declaredMemberScope, session)
|
||||||
|
}
|
||||||
) : FirScopeProvider(), FirSessionComponent {
|
) : FirScopeProvider(), FirSessionComponent {
|
||||||
override fun getUseSiteMemberScope(
|
override fun getUseSiteMemberScope(
|
||||||
klass: FirClass,
|
klass: FirClass,
|
||||||
@@ -109,8 +119,52 @@ class FirKotlinScopeProvider(
|
|||||||
): FirContainingNamesAwareScope? {
|
): FirContainingNamesAwareScope? {
|
||||||
return useSiteSession.nestedClassifierScope(klass)
|
return useSiteSession.nestedClassifierScope(klass)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PlatformDependentFilteringScope(
|
||||||
|
val declaredMemberScope: FirContainingNamesAwareScope,
|
||||||
|
val session: FirSession,
|
||||||
|
) : FirContainingNamesAwareScope() {
|
||||||
|
override fun getCallableNames(): Set<Name> = declaredMemberScope.getCallableNames()
|
||||||
|
|
||||||
|
override fun getClassifierNames(): Set<Name> = declaredMemberScope.getClassifierNames()
|
||||||
|
|
||||||
|
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||||
|
declaredMemberScope.processPropertiesByName(name, processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
||||||
|
declaredMemberScope.processClassifiersByNameWithSubstitution(name, processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
||||||
|
declaredMemberScope.processDeclaredConstructors(processor)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
|
||||||
|
declaredMemberScope.processFunctionsByName(name) {
|
||||||
|
if (FirPlatformDeclarationFilter.isFunctionAvailable(it.fir, session)) {
|
||||||
|
processor(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mayContainName(name: Name): Boolean = declaredMemberScope.mayContainName(name)
|
||||||
|
|
||||||
|
override val scopeOwnerLookupNames: List<String>
|
||||||
|
get() = declaredMemberScope.scopeOwnerLookupNames
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object FirPlatformDeclarationFilter {
|
||||||
|
fun isFunctionAvailable(function: FirSimpleFunction, session: FirSession): Boolean {
|
||||||
|
// Optimization: only check the annotations for functions named "getOrDefault" and "remove",
|
||||||
|
// since only two functions with these names in kotlin.collections.Map are currently annotated with @PlatformDependent.
|
||||||
|
// This also allows to optimize more heavyweight FirJvmPlatformDeclarationFilter as it uses this function
|
||||||
|
return function.name !in namesToCheck || !function.hasAnnotation(StandardNames.FqNames.platformDependentClassId, session)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val namesToCheck = listOf("getOrDefault", "remove").map(Name::identifier)
|
||||||
|
}
|
||||||
|
|
||||||
data class ConeSubstitutionScopeKey(
|
data class ConeSubstitutionScopeKey(
|
||||||
val lookupTag: ConeClassLikeLookupTag,
|
val lookupTag: ConeClassLikeLookupTag,
|
||||||
|
|||||||
+4
-1
@@ -1 +1,4 @@
|
|||||||
OK
|
compiler/testData/cli/metadata/getOrDefault.kt:2:38: error: unresolved reference 'getOrDefault'.
|
||||||
|
fun foo(map: Map<String, Int>) = map.getOrDefault("", 0)
|
||||||
|
^
|
||||||
|
COMPILATION_ERROR
|
||||||
|
|||||||
+1
-1
@@ -12,4 +12,4 @@ public expect abstract class AbstractMutableMap<K, V> : MutableMap<K, V> {
|
|||||||
|
|
||||||
import java.util.AbstractMap
|
import java.util.AbstractMap
|
||||||
|
|
||||||
public actual abstract class <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS, NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>AbstractMutableMap<!><K, V>() : MutableMap<K, V>, AbstractMap<K, V>()
|
public actual abstract class <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>AbstractMutableMap<!><K, V>() : MutableMap<K, V>, AbstractMap<K, V>()
|
||||||
|
|||||||
Reference in New Issue
Block a user