From 375140ebccf81fbcb838a7fd304686bb11c778e8 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Fri, 28 Aug 2020 13:46:05 +0300 Subject: [PATCH] [FIR] Extract java class mapping to platform specific component --- .../kotlin/fir/java/JavaSessionUtils.kt | 2 ++ .../kotlin/fir/resolve/FirJavaClassMapper.kt | 22 ++++++++++++++++++ .../fir/resolve/FirPlatformClassMapper.kt | 23 +++++++++++++++++++ .../kotlin/fir/resolve/SupertypeUtils.kt | 16 ++++++------- 4 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/FirJavaClassMapper.kt create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirPlatformClassMapper.kt diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSessionUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSessionUtils.kt index f4b1e1dadae..66afc03d222 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSessionUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSessionUtils.kt @@ -8,9 +8,11 @@ package org.jetbrains.kotlin.fir.java import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.registerJvmEffectiveVisibilityResolver import org.jetbrains.kotlin.fir.resolve.calls.jvm.registerJvmCallConflictResolverFactory +import org.jetbrains.kotlin.fir.resolve.registerJavaClassMapper fun FirSession.registerJavaSpecificComponents() { registerJavaVisibilityChecker() registerJvmCallConflictResolverFactory() registerJvmEffectiveVisibilityResolver() + registerJavaClassMapper() } diff --git a/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/FirJavaClassMapper.kt b/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/FirJavaClassMapper.kt new file mode 100644 index 00000000000..d886c0af0be --- /dev/null +++ b/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/FirJavaClassMapper.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2020 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 + +import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration +import org.jetbrains.kotlin.fir.declarations.FirRegularClass + +class FirJavaClassMapper(private val session: FirSession) : FirPlatformClassMapper() { + override fun getCorrespondingPlatformClass(declaration: FirClassLikeDeclaration<*>): FirRegularClass? { + val javaClassId = JavaToKotlinClassMap.mapKotlinToJava(declaration.symbol.classId.asSingleFqName().toUnsafe()) + return javaClassId?.let { session.firSymbolProvider.getClassLikeSymbolByFqName(it)?.fir } as? FirRegularClass + } +} + +fun FirSession.registerJavaClassMapper() { + register(FirPlatformClassMapper::class, FirJavaClassMapper(this)) +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirPlatformClassMapper.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirPlatformClassMapper.kt new file mode 100644 index 00000000000..bdcad551131 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirPlatformClassMapper.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2020 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 + +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.FirSessionComponent +import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration +import org.jetbrains.kotlin.fir.declarations.FirRegularClass + +abstract class FirPlatformClassMapper : FirSessionComponent { + object Default : FirPlatformClassMapper() { + override fun getCorrespondingPlatformClass(declaration: FirClassLikeDeclaration<*>): FirRegularClass? { + return null + } + } + + abstract fun getCorrespondingPlatformClass(declaration: FirClassLikeDeclaration<*>): FirRegularClass? +} + +val FirSession.platformClassMapper: FirPlatformClassMapper by FirSession.sessionComponentAccessor() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SupertypeUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SupertypeUtils.kt index 065c96e38e8..a4d9a796d79 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SupertypeUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SupertypeUtils.kt @@ -5,16 +5,15 @@ package org.jetbrains.kotlin.fir.resolve -import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.transformers.createSubstitutionForSupertype -import org.jetbrains.kotlin.fir.typeContext -import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.FirScope +import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope import org.jetbrains.kotlin.fir.symbols.impl.* +import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.name.ClassId @@ -94,16 +93,15 @@ fun ConeClassLikeType.wrapSubstitutionScopeIfNeed( return builder.getOrBuild(declaration.symbol, SubstitutionScopeKey(this)) { val typeParameters = (declaration as? FirTypeParameterRefsOwner)?.typeParameters.orEmpty() val originalSubstitution = createSubstitution(typeParameters, typeArguments, session) - val javaClassId = JavaToKotlinClassMap.mapKotlinToJava(declaration.symbol.classId.asSingleFqName().toUnsafe()) - val javaClass = javaClassId?.let { session.firSymbolProvider.getClassLikeSymbolByFqName(it)?.fir } as? FirRegularClass - if (javaClass != null) { + val platformClass = session.platformClassMapper.getCorrespondingPlatformClass(declaration) + if (platformClass != null) { // This kind of substitution is necessary when method which is mapped from Java (e.g. Java Map.forEach) // is called on an external type, like MyMap, // to determine parameter types properly (e.g. String, String instead of K, V) - val javaTypeParameters = javaClass.typeParameters - val javaSubstitution = createSubstitution(javaTypeParameters, typeArguments, session) + val platformTypeParameters = platformClass.typeParameters + val platformSubstitution = createSubstitution(platformTypeParameters, typeArguments, session) FirClassSubstitutionScope( - session, useSiteMemberScope, builder, originalSubstitution + javaSubstitution, + session, useSiteMemberScope, builder, originalSubstitution + platformSubstitution, skipPrivateMembers = true, derivedClassId = derivedClassId ) } else {