[WASM] Implementation typeOf support

This commit is contained in:
Igor Yakovlev
2021-10-29 15:14:26 +02:00
committed by TeamCityServer
parent 39a389c49a
commit ee7f4c7278
31 changed files with 258 additions and 198 deletions
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.StandardNames.KOTLIN_REFLECT_FQ_NAME
import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.config.AnalysisFlags.allowFullyQualifiedNameInKClass
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.name.FqName
@@ -58,8 +59,11 @@ abstract class AbstractReflectionApiCallChecker(
private val kClass by storageManager.createLazyValue { reflectionTypes.kClass }
protected open fun isAllowedKClassMember(name: Name): Boolean =
name.asString() == "simpleName" || name.asString() == "isInstance"
protected open fun isAllowedKClassMember(name: Name, context: CallCheckerContext): Boolean = when (name.asString()) {
"simpleName", "isInstance" -> true
"qualifiedName" -> context.languageVersionSettings.getFlag(allowFullyQualifiedNameInKClass)
else -> false
}
final override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
if (isWholeReflectionApiAvailable) return
@@ -71,15 +75,19 @@ abstract class AbstractReflectionApiCallChecker(
val containingClass = descriptor.containingDeclaration as? ClassDescriptor ?: return
if (!ReflectionTypes.isReflectionClass(containingClass)) return
if (!isAllowedReflectionApi(descriptor, containingClass)) {
if (!isAllowedReflectionApi(descriptor, containingClass, context)) {
report(reportOn, context)
}
}
protected open fun isAllowedReflectionApi(descriptor: CallableDescriptor, containingClass: ClassDescriptor): Boolean {
protected open fun isAllowedReflectionApi(
descriptor: CallableDescriptor,
containingClass: ClassDescriptor,
context: CallCheckerContext
): Boolean {
val name = descriptor.name
return name.asString() in ALLOWED_MEMBER_NAMES ||
DescriptorUtils.isSubclass(containingClass, kClass) && isAllowedKClassMember(name) ||
DescriptorUtils.isSubclass(containingClass, kClass) && isAllowedKClassMember(name, context) ||
(name.asString() == "get" || name.asString() == "set") && containingClass.isKPropertyClass() ||
containingClass.fqNameSafe in ALLOWED_CLASSES
}