[FIR] Move JvmMappedScope to fir:jvm module

This commit is contained in:
simon.ogorodnik
2020-01-09 17:04:57 +03:00
committed by Mikhail Glukhikh
parent 16c82030a3
commit 5b8ab76613
3 changed files with 2 additions and 2 deletions
@@ -0,0 +1,115 @@
/*
* 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.scopes.jvm
import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.JavaClassifierType
import org.jetbrains.kotlin.load.java.structure.JavaPrimitiveType
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
fun FirFunction<*>.computeJvmDescriptor(): String = buildString {
if (this@computeJvmDescriptor is FirSimpleFunction) {
append(name.asString())
} else {
append("<init>")
}
append("(")
for (parameter in valueParameters) {
appendErasedType(parameter.returnTypeRef)
}
append(")")
if (this@computeJvmDescriptor !is FirSimpleFunction || returnTypeRef.isVoid()) {
append("V")
} else {
appendErasedType(returnTypeRef)
}
}
// TODO: primitive types, arrays, etc.
private fun StringBuilder.appendErasedType(typeRef: FirTypeRef) {
fun appendClass(klass: JavaClass) {
klass.fqName?.let {
append("L")
append(it.asString().replace(".", "/"))
}
}
when (typeRef) {
is FirResolvedTypeRef -> appendConeType(typeRef.type)
is FirJavaTypeRef -> {
when (val javaType = typeRef.type) {
is JavaClassifierType -> {
when (val classifier = javaType.classifier) {
is JavaClass -> appendClass(classifier)
is JavaTypeParameter -> {
val representative = classifier.upperBounds.firstOrNull { it.classifier is JavaClass }
if (representative == null) {
append("Ljava/lang/Object")
} else {
appendClass(representative.classifier as JavaClass)
}
}
else -> return
}
append(";")
}
}
}
}
}
private fun StringBuilder.appendConeType(coneType: ConeKotlinType) {
fun appendClassLikeType(type: ConeClassLikeType) {
append("L")
val classId = type.lookupTag.classId
append(classId.packageFqName.asString().replace(".", "/"))
append("/")
append(classId.relativeClassName)
}
if (coneType is ConeClassErrorType) return
when (coneType) {
is ConeClassLikeType -> {
appendClassLikeType(coneType)
}
is ConeTypeParameterType -> {
val representative = coneType.lookupTag.typeParameterSymbol.fir.bounds.firstOrNull {
(it as? FirResolvedTypeRef)?.type is ConeClassLikeType
}
if (representative == null) {
append("Ljava/lang/Object")
} else {
appendClassLikeType(representative.coneTypeUnsafe())
}
append(coneType.lookupTag.name)
}
}
append(";")
}
private val unitClassId = ClassId.topLevel(FqName("kotlin.Unit"))
private fun FirTypeRef.isVoid(): Boolean {
return when (this) {
is FirJavaTypeRef -> {
val type = type
type is JavaPrimitiveType && type.type == null
}
is FirResolvedTypeRef -> {
val type = type
type is ConeClassLikeType && type.lookupTag.classId == unitClassId
}
else -> false
}
}
@@ -0,0 +1,54 @@
/*
* Copyright 2010-2019 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.scopes.jvm
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltInsSettings
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.name.Name
class JvmMappedScope(
private val declaredMemberScope: FirScope,
private val javaMappedClassUseSiteScope: FirScope,
private val whiteListSignaturesByName: Map<Name, List<String>>
) : FirScope() {
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> ProcessorAction): ProcessorAction {
val whiteListSignatures = whiteListSignaturesByName[name]
?: return declaredMemberScope.processFunctionsByName(name, processor)
if (!javaMappedClassUseSiteScope.processFunctionsByName(name) { symbol ->
val jvmSignature = symbol.fir.computeJvmDescriptor()
if (jvmSignature !in whiteListSignatures) {
ProcessorAction.NEXT
} else {
processor(symbol)
}
}
) return ProcessorAction.STOP
return declaredMemberScope.processFunctionsByName(name, processor)
}
override fun processPropertiesByName(name: Name, processor: (FirCallableSymbol<*>) -> ProcessorAction): ProcessorAction {
return declaredMemberScope.processPropertiesByName(name, processor)
}
companion object {
fun prepareSignatures(klass: FirRegularClass): Map<Name, List<String>> {
val signaturePrefix = klass.symbol.classId.toString()
val filteredSignatures = JvmBuiltInsSettings.WHITE_LIST_METHOD_SIGNATURES.filter { signature ->
signature.startsWith(signaturePrefix)
}.map { signature ->
// +1 to delete dot before function name
signature.substring(signaturePrefix.length + 1)
}
return filteredSignatures.groupBy { Name.identifier(it.substringBefore("(")) }
}
}
}