Support KClass.simpleName in stdlib-only reflection implementation

#KT-33646 Fixed
This commit is contained in:
Alexander Udalov
2019-10-24 18:33:46 +02:00
parent e146d308db
commit c164745301
15 changed files with 138 additions and 77 deletions
@@ -20,18 +20,14 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.NotFoundClasses
import org.jetbrains.kotlin.diagnostics.Errors.UNSUPPORTED
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.checkers.AbstractReflectionApiCallChecker
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.storage.getValue
private val ALLOWED_KCLASS_MEMBERS = setOf("simpleName", "isInstance")
private val ALLOWED_CLASSES = setOf(
FqName("kotlin.reflect.KType"),
FqName("kotlin.reflect.KTypeProjection"),
@@ -40,11 +36,12 @@ private val ALLOWED_CLASSES = setOf(
)
class JsReflectionAPICallChecker(
module: ModuleDescriptor,
private val reflectionTypes: ReflectionTypes,
notFoundClasses: NotFoundClasses,
reflectionTypes: ReflectionTypes,
storageManager: StorageManager
) : AbstractReflectionApiCallChecker(module, notFoundClasses, storageManager) {
) : AbstractReflectionApiCallChecker(reflectionTypes, storageManager) {
override fun isAllowedKClassMember(name: Name): Boolean =
super.isAllowedKClassMember(name) || name.asString() == "isInstance"
override val isWholeReflectionApiAvailable: Boolean
get() = false
@@ -52,10 +49,6 @@ class JsReflectionAPICallChecker(
context.trace.report(UNSUPPORTED.on(element, "This reflection API is not supported yet in JavaScript"))
}
private val kClass by storageManager.createLazyValue { reflectionTypes.kClass }
override fun isAllowedReflectionApi(descriptor: CallableDescriptor, containingClass: ClassDescriptor): Boolean =
super.isAllowedReflectionApi(descriptor, containingClass) ||
DescriptorUtils.isSubclass(containingClass, kClass) && descriptor.name.asString() in ALLOWED_KCLASS_MEMBERS ||
containingClass.fqNameSafe in ALLOWED_CLASSES
super.isAllowedReflectionApi(descriptor, containingClass) || containingClass.fqNameSafe in ALLOWED_CLASSES
}