[FIR] Extract expect actual matching into separate phase
This commit is contained in:
committed by
teamcity
parent
de842817e8
commit
d66748d011
+1
-1
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirEle
|
||||
import org.jetbrains.kotlin.fir.FirRenderer
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.ConeTypeCompatibilityChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.ConeTypeCompatibilityChecker.isCompatible
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.fullyExpandedClass
|
||||
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.typeParameterSymbols
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
|
||||
|
||||
+1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.fir.isPrimitiveType
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
|
||||
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock
|
||||
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.SessionHolder
|
||||
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
|
||||
@@ -139,20 +140,6 @@ fun FirClassSymbol<*>.getContainingDeclarationSymbol(session: FirSession): FirCl
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the FirClassLikeDeclaration that the
|
||||
* sequence of FirTypeAlias'es points to starting
|
||||
* with `this`. Or null if something goes wrong or we have anonymous object symbol.
|
||||
*/
|
||||
tailrec fun FirClassLikeSymbol<*>.fullyExpandedClass(useSiteSession: FirSession): FirRegularClassSymbol? {
|
||||
return when (this) {
|
||||
is FirRegularClassSymbol -> this
|
||||
is FirAnonymousObjectSymbol -> null
|
||||
is FirTypeAliasSymbol -> resolvedExpandedTypeRef.coneTypeSafe<ConeClassLikeType>()
|
||||
?.toSymbol(useSiteSession)?.fullyExpandedClass(useSiteSession)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the closest to the end of context.containingDeclarations
|
||||
* item like FirRegularClass or FirAnonymousObject
|
||||
@@ -575,11 +562,6 @@ fun extractArgumentsTypeRefAndSource(typeRef: FirTypeRef?): List<FirTypeRefSourc
|
||||
|
||||
data class FirTypeRefSource(val typeRef: FirTypeRef?, val source: KtSourceElement?)
|
||||
|
||||
fun FirRegularClassSymbol.collectEnumEntries(): Collection<FirEnumEntrySymbol> {
|
||||
assert(classKind == ClassKind.ENUM_CLASS)
|
||||
return declarationSymbols.filterIsInstance<FirEnumEntrySymbol>()
|
||||
}
|
||||
|
||||
val FirClassLikeSymbol<*>.classKind: ClassKind?
|
||||
get() = (this as? FirClassSymbol<*>)?.classKind
|
||||
|
||||
|
||||
+5
-31
@@ -13,13 +13,12 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isActual
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||
@@ -46,9 +45,8 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
reporter: DiagnosticReporter,
|
||||
checkActual: Boolean = true
|
||||
) {
|
||||
val scopeSession = ScopeSession()
|
||||
val symbol = declaration.symbol
|
||||
val compatibilityToMembersMap = FirExpectActualResolver.findExpectForActual(symbol, context.session, scopeSession) ?: return
|
||||
val compatibilityToMembersMap = symbol.expectForActual ?: return
|
||||
val session = context.session
|
||||
|
||||
checkAmbiguousExpects(symbol, compatibilityToMembersMap, symbol, context, reporter)
|
||||
@@ -81,14 +79,11 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
): Boolean {
|
||||
val (expectedMember, incompatibility) = expectedWithIncompatibility
|
||||
val actualMember = incompatibility.values.singleOrNull()?.singleOrNull()
|
||||
@OptIn(SymbolInternals::class)
|
||||
return actualMember != null &&
|
||||
actualMember.isExplicitActualDeclaration() &&
|
||||
!incompatibility.allStrongIncompatibilities() &&
|
||||
FirExpectActualResolver.findExpectForActual(
|
||||
actualMember,
|
||||
session,
|
||||
scopeSession
|
||||
)?.values?.singleOrNull()?.singleOrNull() == expectedMember
|
||||
actualMember.fir.expectForActual?.values?.singleOrNull()?.singleOrNull() == expectedMember
|
||||
}
|
||||
|
||||
val nonTrivialUnfulfilled = singleIncompatibility.unfulfilled.filterNot(::hasSingleActualSuspect)
|
||||
@@ -212,27 +207,6 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
}
|
||||
}
|
||||
|
||||
fun FirBasedSymbol<*>.isAnnotationConstructor(session: FirSession): Boolean {
|
||||
if (this !is FirConstructorSymbol) return false
|
||||
return getConstructedClass(session)?.classKind == ClassKind.ANNOTATION_CLASS
|
||||
}
|
||||
|
||||
fun FirBasedSymbol<*>.isEnumConstructor(session: FirSession): Boolean {
|
||||
if (this !is FirConstructorSymbol) return false
|
||||
return getConstructedClass(session)?.classKind == ClassKind.ENUM_CLASS
|
||||
}
|
||||
|
||||
fun FirBasedSymbol<*>.isPrimaryConstructorOfInlineClass(session: FirSession): Boolean {
|
||||
if (this !is FirConstructorSymbol) return false
|
||||
return getConstructedClass(session)?.isInlineOrValueClass() == true && this.isPrimary
|
||||
}
|
||||
|
||||
fun FirConstructorSymbol.getConstructedClass(session: FirSession): FirRegularClassSymbol? {
|
||||
return resolvedReturnTypeRef.coneType
|
||||
.fullyExpandedType(session)
|
||||
.toSymbol(session) as? FirRegularClassSymbol?
|
||||
}
|
||||
|
||||
fun FirBasedSymbol<*>.expandedClass(session: FirSession): FirRegularClassSymbol? {
|
||||
return when (this) {
|
||||
is FirTypeAliasSymbol -> resolvedExpandedTypeRef.coneType.fullyExpandedType(session).toSymbol(session) as? FirRegularClassSymbol
|
||||
|
||||
+1
-2
@@ -7,10 +7,9 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.collectEnumEntries
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirDeprecationChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.fullyExpandedClass
|
||||
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
|
||||
|
||||
@Suppress("NAME_SHADOWING")
|
||||
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (!declaration.isInlineOrValueClass()) {
|
||||
if (!declaration.symbol.isInlineOrValueClass()) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
-12
@@ -78,18 +78,6 @@ internal fun FirMemberDeclaration.isEffectivelyExternal(
|
||||
|
||||
internal val FirClass.canHaveOpenMembers: Boolean get() = modality() != Modality.FINAL || classKind == ClassKind.ENUM_CLASS
|
||||
|
||||
internal fun FirRegularClass.isInlineOrValueClass(): Boolean {
|
||||
if (this.classKind != ClassKind.CLASS) return false
|
||||
|
||||
return isInline || hasModifier(KtTokens.VALUE_KEYWORD)
|
||||
}
|
||||
|
||||
internal fun FirRegularClassSymbol.isInlineOrValueClass(): Boolean {
|
||||
if (this.classKind != ClassKind.CLASS) return false
|
||||
|
||||
return isInline
|
||||
}
|
||||
|
||||
internal val FirDeclaration.isEnumEntryInitializer: Boolean
|
||||
get() {
|
||||
if (this !is FirConstructor || !this.isPrimary) return false
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.findClosestClassOrObject
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.fullyExpandedClass
|
||||
import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.isSupertypeOf
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.toClassLikeSymbol
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
|
||||
+2
-2
@@ -9,12 +9,12 @@ import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.collectEnumEntries
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.getChild
|
||||
import org.jetbrains.kotlin.fir.declarations.FirErrorImport
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.collectEnumEntries
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isEnumClass
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedParentInImport
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
@@ -92,4 +92,4 @@ object FirUnresolvedInMiddleOfImportChecker : FirDeclarationSyntaxChecker<FirFil
|
||||
|
||||
private fun KtSourceElement.dotQualifiedExpression() = getChild(KtNodeTypes.DOT_QUALIFIED_EXPRESSION, depth = 1)
|
||||
private fun KtSourceElement.selectorExpression() = getChild(KtNodeTypes.REFERENCE_EXPRESSION, depth = 1, reverse = true)
|
||||
}
|
||||
}
|
||||
|
||||
+53
-1
@@ -7,8 +7,15 @@ package org.jetbrains.kotlin.fir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isInline
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||
import org.jetbrains.kotlin.fir.types.toSymbol
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
|
||||
fun FirClass.constructors(session: FirSession): List<FirConstructorSymbol> {
|
||||
@@ -30,6 +37,10 @@ fun FirRegularClass.collectEnumEntries(): Collection<FirEnumEntry> {
|
||||
return declarations.filterIsInstance<FirEnumEntry>()
|
||||
}
|
||||
|
||||
fun FirRegularClassSymbol.collectEnumEntries(): Collection<FirEnumEntrySymbol> {
|
||||
return fir.collectEnumEntries().map { it.symbol }
|
||||
}
|
||||
|
||||
val FirConstructorSymbol.delegatedThisConstructor: FirConstructorSymbol?
|
||||
get() = runIf(delegatedConstructorCallIsThis) { this.resolvedDelegatedConstructor }
|
||||
|
||||
@@ -46,3 +57,44 @@ private object ConstructorDelegationComparator : Comparator<FirConstructorSymbol
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the FirClassLikeDeclaration that the
|
||||
* sequence of FirTypeAlias'es points to starting
|
||||
* with `this`. Or null if something goes wrong or we have anonymous object symbol.
|
||||
*/
|
||||
tailrec fun FirClassLikeSymbol<*>.fullyExpandedClass(useSiteSession: FirSession): FirRegularClassSymbol? {
|
||||
return when (this) {
|
||||
is FirRegularClassSymbol -> this
|
||||
is FirAnonymousObjectSymbol -> null
|
||||
is FirTypeAliasSymbol -> resolvedExpandedTypeRef.coneTypeSafe<ConeClassLikeType>()
|
||||
?.toSymbol(useSiteSession)?.fullyExpandedClass(useSiteSession)
|
||||
}
|
||||
}
|
||||
|
||||
fun FirBasedSymbol<*>.isAnnotationConstructor(session: FirSession): Boolean {
|
||||
if (this !is FirConstructorSymbol) return false
|
||||
return getConstructedClass(session)?.classKind == ClassKind.ANNOTATION_CLASS
|
||||
}
|
||||
|
||||
fun FirBasedSymbol<*>.isEnumConstructor(session: FirSession): Boolean {
|
||||
if (this !is FirConstructorSymbol) return false
|
||||
return getConstructedClass(session)?.classKind == ClassKind.ENUM_CLASS
|
||||
}
|
||||
|
||||
fun FirBasedSymbol<*>.isPrimaryConstructorOfInlineClass(session: FirSession): Boolean {
|
||||
if (this !is FirConstructorSymbol) return false
|
||||
return getConstructedClass(session)?.isInlineOrValueClass() == true && this.isPrimary
|
||||
}
|
||||
|
||||
fun FirConstructorSymbol.getConstructedClass(session: FirSession): FirRegularClassSymbol? {
|
||||
return resolvedReturnTypeRef.coneType
|
||||
.fullyExpandedType(session)
|
||||
.toSymbol(session) as? FirRegularClassSymbol?
|
||||
}
|
||||
|
||||
fun FirRegularClassSymbol.isInlineOrValueClass(): Boolean {
|
||||
if (this.classKind != ClassKind.CLASS) return false
|
||||
|
||||
return isInline
|
||||
}
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ abstract class FirTransformerBasedResolveProcessor(
|
||||
) : FirResolveProcessor(session, scopeSession) {
|
||||
abstract val transformer: FirTransformer<Nothing?>
|
||||
|
||||
fun processFile(file: FirFile) {
|
||||
open fun processFile(file: FirFile) {
|
||||
file.transform<FirFile, Nothing?>(transformer, null)
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveProcessor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirImplicitTypeBodyResolveProcessor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.contracts.FirContractResolveProcessor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.mpp.FirExpectActualMatcherProcessor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.plugin.*
|
||||
|
||||
class FirTotalResolveProcessor(session: FirSession) {
|
||||
@@ -79,5 +80,6 @@ fun FirResolvePhase.createCompilerProcessorByPhase(
|
||||
CONTRACTS -> FirContractResolveProcessor(session, scopeSession)
|
||||
IMPLICIT_TYPES_BODY_RESOLVE -> FirImplicitTypeBodyResolveProcessor(session, scopeSession)
|
||||
BODY_RESOLVE -> FirBodyResolveProcessor(session, scopeSession)
|
||||
EXPECT_ACTUAL_MATCHING -> FirExpectActualMatcherProcessor(session, scopeSession)
|
||||
}
|
||||
}
|
||||
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.transformers.mpp
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isActual
|
||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirAbstractTreeTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTransformerBasedResolveProcessor
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.compatible
|
||||
|
||||
class FirExpectActualMatcherProcessor(
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession
|
||||
) : FirTransformerBasedResolveProcessor(session, scopeSession) {
|
||||
private val enabled = session.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)
|
||||
|
||||
override val transformer: FirTransformer<Nothing?> = FirExpectActualMatcherTransformer(session, scopeSession)
|
||||
|
||||
override fun processFile(file: FirFile) {
|
||||
if (!enabled) return
|
||||
super.processFile(file)
|
||||
}
|
||||
}
|
||||
|
||||
class FirExpectActualMatcherTransformer(
|
||||
override val session: FirSession,
|
||||
private val scopeSession: ScopeSession
|
||||
) : FirAbstractTreeTransformer<Nothing?>(FirResolvePhase.EXPECT_ACTUAL_MATCHING) {
|
||||
|
||||
// --------------------------- classifiers ---------------------------
|
||||
override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Nothing?): FirStatement {
|
||||
transformMemberDeclaration(typeAlias)
|
||||
return typeAlias
|
||||
}
|
||||
|
||||
override fun transformRegularClass(regularClass: FirRegularClass, data: Nothing?): FirStatement {
|
||||
transformMemberDeclaration(regularClass)
|
||||
regularClass.transformChildren(this, data)
|
||||
return regularClass
|
||||
}
|
||||
|
||||
// --------------------------- callable declaration ---------------------------
|
||||
override fun transformEnumEntry(enumEntry: FirEnumEntry, data: Nothing?): FirStatement {
|
||||
transformMemberDeclaration(enumEntry)
|
||||
return enumEntry
|
||||
}
|
||||
|
||||
override fun transformProperty(property: FirProperty, data: Nothing?): FirStatement {
|
||||
transformMemberDeclaration(property)
|
||||
return property
|
||||
}
|
||||
|
||||
override fun transformConstructor(constructor: FirConstructor, data: Nothing?): FirStatement {
|
||||
transformMemberDeclaration(constructor)
|
||||
return constructor
|
||||
}
|
||||
|
||||
override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: Nothing?): FirStatement {
|
||||
transformMemberDeclaration(simpleFunction)
|
||||
return simpleFunction
|
||||
}
|
||||
|
||||
// --------------------------- other ---------------------------
|
||||
override fun transformAnonymousInitializer(anonymousInitializer: FirAnonymousInitializer, data: Nothing?): FirAnonymousInitializer {
|
||||
return anonymousInitializer
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
|
||||
private fun transformMemberDeclaration(memberDeclaration: FirMemberDeclaration) {
|
||||
if (!memberDeclaration.isActual) return
|
||||
val actualSymbol = memberDeclaration.symbol
|
||||
val expectForActualData = FirExpectActualResolver.findExpectForActual(
|
||||
actualSymbol,
|
||||
session,
|
||||
scopeSession
|
||||
) ?: return
|
||||
memberDeclaration.expectForActual = expectForActualData
|
||||
for ((compatibility, expectSymbols) in expectForActualData) {
|
||||
if (compatibility.compatible) {
|
||||
for (expectSymbol in expectSymbols) {
|
||||
expectSymbol.fir.setActualForExpect(session, actualSymbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-8
@@ -1,18 +1,16 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
package org.jetbrains.kotlin.fir.resolve.transformers.mpp
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Modality.*
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.collectEnumEntries
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.fullyExpandedClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.dependenciesSymbolProvider
|
||||
@@ -43,7 +41,7 @@ object FirExpectActualResolver {
|
||||
actualSymbol: FirBasedSymbol<*>,
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession
|
||||
): Map<ExpectActualCompatibility<FirBasedSymbol<*>>, List<FirBasedSymbol<*>>>? {
|
||||
): ExpectForActualData? {
|
||||
return when (actualSymbol) {
|
||||
is FirCallableSymbol<*> -> {
|
||||
val callableId = actualSymbol.callableId
|
||||
@@ -228,8 +226,8 @@ object FirExpectActualResolver {
|
||||
}
|
||||
|
||||
if (expectClassSymbol.classKind == ClassKind.ENUM_CLASS) {
|
||||
val expectEntries = expectClassSymbol.collectEnumEntries().map { it.name }
|
||||
val actualEntries = actualClassSymbol.collectEnumEntries().map { it.name }
|
||||
val expectEntries = expectClassSymbol.fir.collectEnumEntries().map { it.name }
|
||||
val actualEntries = actualClassSymbol.fir.collectEnumEntries().map { it.name }
|
||||
|
||||
if (!actualEntries.containsAll(expectEntries)) {
|
||||
return ExpectActualCompatibility.Incompatible.EnumEntries
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.ensureResolved
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
|
||||
import java.util.*
|
||||
|
||||
private object ExpectForActualAttributeKey : FirDeclarationDataKey()
|
||||
private object ActualForExpectAttributeKey : FirDeclarationDataKey()
|
||||
|
||||
typealias ExpectForActualData = Map<ExpectActualCompatibility<FirBasedSymbol<*>>, List<FirBasedSymbol<*>>>
|
||||
|
||||
@SymbolInternals
|
||||
var FirDeclaration.expectForActual: ExpectForActualData? by FirDeclarationDataRegistry.data(ExpectForActualAttributeKey)
|
||||
private var FirDeclaration.actualForExpectMap: WeakHashMap<FirSession, FirBasedSymbol<*>>? by FirDeclarationDataRegistry.data(ActualForExpectAttributeKey)
|
||||
|
||||
val FirBasedSymbol<*>.expectForActual: ExpectForActualData?
|
||||
get() {
|
||||
ensureResolved(FirResolvePhase.EXPECT_ACTUAL_MATCHING)
|
||||
return fir.expectForActual
|
||||
}
|
||||
|
||||
private fun FirDeclaration.getOrCreateActualForExpectMap(): WeakHashMap<FirSession, FirBasedSymbol<*>> {
|
||||
var map = actualForExpectMap
|
||||
if (map != null) return map
|
||||
synchronized(this) {
|
||||
map = actualForExpectMap
|
||||
if (map == null) {
|
||||
map = WeakHashMap()
|
||||
actualForExpectMap = map
|
||||
}
|
||||
}
|
||||
return map!!
|
||||
}
|
||||
|
||||
@SymbolInternals
|
||||
fun FirDeclaration.getActualForExpect(useSiteSession: FirSession): FirBasedSymbol<*>? {
|
||||
return actualForExpectMap?.get(useSiteSession)
|
||||
}
|
||||
|
||||
fun FirBasedSymbol<*>.getActualForExpect(session: FirSession): FirBasedSymbol<*>? {
|
||||
ensureResolved(FirResolvePhase.EXPECT_ACTUAL_MATCHING)
|
||||
return fir.getActualForExpect(session)
|
||||
}
|
||||
|
||||
@SymbolInternals
|
||||
fun FirDeclaration.setActualForExpect(useSiteSession: FirSession, actualSymbol: FirBasedSymbol<*>) {
|
||||
val map = getOrCreateActualForExpectMap()
|
||||
map[useSiteSession] = actualSymbol
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ enum class FirResolvePhase(val noProcessor: Boolean = false) {
|
||||
ARGUMENTS_OF_ANNOTATIONS,
|
||||
CONTRACTS,
|
||||
IMPLICIT_TYPES_BODY_RESOLVE,
|
||||
EXPECT_ACTUAL_MATCHING,
|
||||
BODY_RESOLVE;
|
||||
|
||||
val requiredToLaunch: FirResolvePhase
|
||||
|
||||
+1
@@ -3,6 +3,7 @@
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// IGNORE_BACKEND: JS_IR_ES6
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
// MODULE: lib-common
|
||||
// FILE: common.kt
|
||||
|
||||
+3
@@ -89,3 +89,6 @@ sealed class ExpectActualCompatibility<out D> {
|
||||
|
||||
object Compatible : ExpectActualCompatibility<Nothing>()
|
||||
}
|
||||
|
||||
val ExpectActualCompatibility<*>.compatible: Boolean
|
||||
get() = this == ExpectActualCompatibility.Compatible
|
||||
|
||||
Reference in New Issue
Block a user