[WASM] Implementation typeOf support
This commit is contained in:
committed by
TeamCityServer
parent
39a389c49a
commit
ee7f4c7278
+1
@@ -404,6 +404,7 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
|
||||
put(AnalysisFlags.extendedCompilerChecks, extendedCompilerChecks)
|
||||
put(AnalysisFlags.allowKotlinPackage, allowKotlinPackage)
|
||||
put(AnalysisFlags.builtInsFromSources, builtInsFromSources)
|
||||
put(AnalysisFlags.allowFullyQualifiedNameInKClass, true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
@@ -7,7 +7,10 @@ package org.jetbrains.kotlin.cli.common.arguments
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.*
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag
|
||||
import org.jetbrains.kotlin.config.AnalysisFlags.allowFullyQualifiedNameInKClass
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersion
|
||||
|
||||
class K2JSCompilerArguments : CommonCompilerArguments() {
|
||||
companion object {
|
||||
@@ -242,6 +245,15 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
|
||||
)
|
||||
var wasmLauncher: String? by NullableStringFreezableVar("esm")
|
||||
|
||||
@Argument(value = "-Xwasm-kclass-fqn", description = "Enable support for FQ names in KClass")
|
||||
var wasmKClassFqn: Boolean by FreezableVar(false)
|
||||
|
||||
override fun configureAnalysisFlags(collector: MessageCollector, languageVersion: LanguageVersion): MutableMap<AnalysisFlag<*>, Any> {
|
||||
return super.configureAnalysisFlags(collector, languageVersion).also {
|
||||
it[allowFullyQualifiedNameInKClass] = wasm && wasmKClassFqn //Only enabled WASM BE supports this flag
|
||||
}
|
||||
}
|
||||
|
||||
override fun configureLanguageFeatures(collector: MessageCollector): MutableMap<LanguageFeature, LanguageFeature.State> {
|
||||
return super.configureLanguageFeatures(collector).apply {
|
||||
if (extensionFunctionsInExternals) {
|
||||
|
||||
@@ -56,4 +56,7 @@ object AnalysisFlags {
|
||||
|
||||
@JvmStatic
|
||||
val builtInsFromSources by AnalysisFlag.Delegates.Boolean
|
||||
|
||||
@JvmStatic
|
||||
val allowFullyQualifiedNameInKClass by AnalysisFlag.Delegates.Boolean
|
||||
}
|
||||
|
||||
-2
@@ -37,8 +37,6 @@ class JvmReflectionAPICallChecker(
|
||||
reflectionTypes: ReflectionTypes,
|
||||
storageManager: StorageManager
|
||||
) : AbstractReflectionApiCallChecker(reflectionTypes, storageManager) {
|
||||
override fun isAllowedKClassMember(name: Name): Boolean =
|
||||
super.isAllowedKClassMember(name) || name.asString() == "qualifiedName"
|
||||
|
||||
override val isWholeReflectionApiAvailable by storageManager.createLazyValue {
|
||||
module.findClassAcrossModuleDependencies(JvmAbi.REFLECTION_FACTORY_IMPL) != null
|
||||
|
||||
+13
-5
@@ -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
|
||||
}
|
||||
|
||||
@@ -415,7 +415,7 @@ fun usefulDeclarations(
|
||||
}
|
||||
}
|
||||
}
|
||||
context.intrinsics.jsGetKClassFromExpression -> {
|
||||
context.reflectionSymbols.getKClassFromExpression -> {
|
||||
val ref = expression.getTypeArgument(0)?.classOrNull ?: context.irBuiltIns.anyClass
|
||||
referencedJsClassesFromExpressions += ref.owner
|
||||
}
|
||||
|
||||
+1
-5
@@ -30,16 +30,12 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
interface JsCommonBackendContext : CommonBackendContext {
|
||||
override val mapping: JsMapping
|
||||
|
||||
val intrinsics: Intrinsics
|
||||
|
||||
val dynamicType: IrDynamicType
|
||||
val reflectionSymbols: ReflectionSymbols
|
||||
|
||||
val inlineClassesUtils: InlineClassesUtils
|
||||
|
||||
val coroutineSymbols: JsCommonCoroutineSymbols
|
||||
|
||||
val primitiveClassesObject: IrClassSymbol
|
||||
|
||||
val catchAllThrowableType: IrType
|
||||
get() = irBuiltIns.throwableType
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.isLong
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
@@ -21,21 +22,7 @@ import org.jetbrains.kotlin.psi2ir.findSingleFunction
|
||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
|
||||
import java.util.*
|
||||
|
||||
interface Intrinsics {
|
||||
val jsGetKClassFromExpression: IrSimpleFunctionSymbol
|
||||
val jsGetKClass: IrSimpleFunctionSymbol
|
||||
val jsClass: IrSimpleFunctionSymbol
|
||||
val createKType: IrSimpleFunctionSymbol?
|
||||
val createDynamicKType: IrSimpleFunctionSymbol?
|
||||
val createKTypeParameter: IrSimpleFunctionSymbol?
|
||||
val getStarKTypeProjection: IrSimpleFunctionSymbol?
|
||||
val createCovariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||
val createInvariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||
val createContravariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||
val arrayLiteral: IrSimpleFunctionSymbol
|
||||
}
|
||||
|
||||
class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendContext) : Intrinsics {
|
||||
class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendContext) {
|
||||
|
||||
// TODO: Should we drop operator intrinsics in favor of IrDynamicOperatorExpression?
|
||||
|
||||
@@ -184,10 +171,6 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
||||
val jsInvokeSuspendSuperTypeWithReceiverAndParam =
|
||||
getInternalWithoutPackage("kotlin.coroutines.intrinsics.invokeSuspendSuperTypeWithReceiverAndParam")
|
||||
|
||||
override val jsGetKClass = getInternalWithoutPackage("getKClass")
|
||||
override val jsGetKClassFromExpression = getInternalWithoutPackage("getKClassFromExpression")
|
||||
override val jsClass = getInternalFunction("jsClassIntrinsic")
|
||||
|
||||
val jsNumberRangeToNumber = getInternalFunction("numberRangeToNumber")
|
||||
val jsNumberRangeToLong = getInternalFunction("numberRangeToLong")
|
||||
|
||||
@@ -249,7 +232,25 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
||||
val jsPrimitiveArrayIteratorFunctions =
|
||||
PrimitiveType.values().associate { it to getInternalFunction("${it.typeName.asString().toLowerCaseAsciiOnly()}ArrayIterator") }
|
||||
|
||||
override val arrayLiteral = getInternalFunction("arrayLiteral")
|
||||
val jsClass = getInternalFunction("jsClassIntrinsic")
|
||||
val arrayLiteral: IrSimpleFunctionSymbol = getInternalFunction("arrayLiteral")
|
||||
|
||||
internal inner class JsReflectionSymbols : ReflectionSymbols {
|
||||
override val createKType = getInternalWithoutPackageOrNull("createKType")
|
||||
override val createDynamicKType = getInternalWithoutPackageOrNull("createDynamicKType")
|
||||
override val createKTypeParameter = getInternalWithoutPackageOrNull("createKTypeParameter")
|
||||
override val getStarKTypeProjection = getInternalWithoutPackageOrNull("getStarKTypeProjection")
|
||||
override val createCovariantKTypeProjection = getInternalWithoutPackageOrNull("createCovariantKTypeProjection")
|
||||
override val createInvariantKTypeProjection = getInternalWithoutPackageOrNull("createInvariantKTypeProjection")
|
||||
override val createContravariantKTypeProjection = getInternalWithoutPackageOrNull("createContravariantKTypeProjection")
|
||||
override val getKClass = getInternalWithoutPackage("getKClass")
|
||||
override val getKClassFromExpression = getInternalWithoutPackage("getKClassFromExpression")
|
||||
override val primitiveClassesObject = context.getIrClass(FqName("kotlin.reflect.js.internal.PrimitiveClasses"))
|
||||
override val kTypeClass: IrClassSymbol = context.getIrClass(FqName("kotlin.reflect.KType"))
|
||||
override val getClassData: IrSimpleFunctionSymbol get() = jsClass
|
||||
}
|
||||
|
||||
internal val reflectionSymbols: JsReflectionSymbols = JsReflectionSymbols()
|
||||
|
||||
val primitiveToTypedArrayMap = EnumMap(
|
||||
mapOf(
|
||||
@@ -261,14 +262,6 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
||||
)
|
||||
)
|
||||
|
||||
override val createKType = getInternalWithoutPackageOrNull("createKType")
|
||||
override val createDynamicKType = getInternalWithoutPackageOrNull("createDynamicKType")
|
||||
override val createKTypeParameter = getInternalWithoutPackageOrNull("createKTypeParameter")
|
||||
override val getStarKTypeProjection = getInternalWithoutPackageOrNull("getStarKTypeProjection")
|
||||
override val createCovariantKTypeProjection = getInternalWithoutPackageOrNull("createCovariantKTypeProjection")
|
||||
override val createInvariantKTypeProjection = getInternalWithoutPackageOrNull("createInvariantKTypeProjection")
|
||||
override val createContravariantKTypeProjection = getInternalWithoutPackageOrNull("createContravariantKTypeProjection")
|
||||
|
||||
val primitiveToSizeConstructor =
|
||||
PrimitiveType.values().associate { type ->
|
||||
type to (primitiveToTypedArrayMap[type]?.let {
|
||||
|
||||
@@ -157,8 +157,9 @@ class JsIrBackendContext(
|
||||
|
||||
private val internalPackage = module.getPackage(JS_PACKAGE_FQNAME)
|
||||
|
||||
override val dynamicType: IrDynamicType = IrDynamicTypeImpl(null, emptyList(), Variance.INVARIANT)
|
||||
override val intrinsics = JsIntrinsics(irBuiltIns, this)
|
||||
val dynamicType: IrDynamicType = IrDynamicTypeImpl(null, emptyList(), Variance.INVARIANT)
|
||||
val intrinsics: JsIntrinsics = JsIntrinsics(irBuiltIns, this)
|
||||
override val reflectionSymbols: ReflectionSymbols get() = intrinsics.reflectionSymbols
|
||||
|
||||
override val catchAllThrowableType: IrType
|
||||
get() = dynamicType
|
||||
@@ -284,16 +285,12 @@ class JsIrBackendContext(
|
||||
val errorCodeSymbol: IrSimpleFunctionSymbol? =
|
||||
if (errorPolicy.allowErrors) symbolTable.referenceSimpleFunction(getJsInternalFunction("errorCode")) else null
|
||||
|
||||
override val primitiveClassesObject = getIrClass(FqName("kotlin.reflect.js.internal.PrimitiveClasses"))
|
||||
|
||||
val throwableClass = getIrClass(JsIrBackendContext.KOTLIN_PACKAGE_FQN.child(Name.identifier("Throwable")))
|
||||
|
||||
val primitiveCompanionObjects = primitivesWithImplicitCompanionObject().associateWith {
|
||||
getIrClass(JS_INTERNAL_PACKAGE_FQNAME.child(Name.identifier("${it.identifier}CompanionObject")))
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Top-level functions forced to be loaded
|
||||
|
||||
|
||||
@@ -355,7 +352,7 @@ class JsIrBackendContext(
|
||||
internal fun getProperty(fqName: FqName): PropertyDescriptor =
|
||||
findProperty(module.getPackage(fqName.parent()).memberScope, fqName.shortName()).single()
|
||||
|
||||
private fun getIrClass(fqName: FqName): IrClassSymbol = symbolTable.referenceClass(getClass(fqName))
|
||||
internal fun getIrClass(fqName: FqName): IrClassSymbol = symbolTable.referenceClass(getClass(fqName))
|
||||
|
||||
internal fun getJsInternalFunction(name: String): SimpleFunctionDescriptor =
|
||||
findFunctions(internalPackage.memberScope, Name.identifier(name)).singleOrNull() ?: error("Internal function '$name' not found")
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.ir.backend.js
|
||||
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
|
||||
interface ReflectionSymbols {
|
||||
val getKClassFromExpression: IrSimpleFunctionSymbol
|
||||
val getKClass: IrSimpleFunctionSymbol
|
||||
val getClassData: IrSimpleFunctionSymbol
|
||||
val createKType: IrSimpleFunctionSymbol?
|
||||
val createDynamicKType: IrSimpleFunctionSymbol?
|
||||
val createKTypeParameter: IrSimpleFunctionSymbol?
|
||||
val getStarKTypeProjection: IrSimpleFunctionSymbol?
|
||||
val createCovariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||
val createInvariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||
val createContravariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||
val primitiveClassesObject: IrClassSymbol
|
||||
val kTypeClass: IrClassSymbol
|
||||
}
|
||||
+37
-29
@@ -8,9 +8,10 @@ package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||
import org.jetbrains.kotlin.backend.common.ir.createArrayOfExpression
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.backend.js.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.toJsArrayLiteral
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
@@ -25,21 +26,22 @@ import org.jetbrains.kotlin.types.*
|
||||
|
||||
class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLoweringPass {
|
||||
|
||||
private val reflectionSymbols get() = context.reflectionSymbols
|
||||
|
||||
private val primitiveClassProperties by lazy {
|
||||
primitiveClassesObject.owner.declarations.filterIsInstance<IrProperty>()
|
||||
reflectionSymbols.primitiveClassesObject.owner.declarations.filterIsInstance<IrProperty>()
|
||||
}
|
||||
|
||||
private val primitiveClassFunctionClass by lazy {
|
||||
primitiveClassesObject.owner.declarations
|
||||
reflectionSymbols.primitiveClassesObject.owner.declarations
|
||||
.filterIsInstance<IrSimpleFunction>()
|
||||
.find { it.name == Name.identifier("functionClass") }!!
|
||||
}
|
||||
|
||||
private val primitiveClassesObject = context.primitiveClassesObject
|
||||
|
||||
private fun primitiveClassProperty(name: String) =
|
||||
primitiveClassProperties.singleOrNull { it.name == Name.identifier(name) }?.getter
|
||||
?: primitiveClassesObject.owner.declarations.filterIsInstance<IrSimpleFunction>().single { it.name == Name.special("<get-$name>") }
|
||||
?: reflectionSymbols.primitiveClassesObject.owner.declarations
|
||||
.filterIsInstance<IrSimpleFunction>().single { it.name == Name.special("<get-$name>") }
|
||||
|
||||
private val finalPrimitiveClasses by lazy {
|
||||
mapOf(
|
||||
@@ -80,14 +82,17 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
if (primitiveKClass != null)
|
||||
return JsIrBuilder.buildBlock(returnType, listOf(argument, primitiveKClass))
|
||||
|
||||
return JsIrBuilder.buildCall(context.intrinsics.jsGetKClassFromExpression, returnType, listOf(typeArgument)).apply {
|
||||
return JsIrBuilder.buildCall(reflectionSymbols.getKClassFromExpression, returnType, listOf(typeArgument)).apply {
|
||||
putValueArgument(0, argument)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPrimitiveClass(target: IrSimpleFunction, returnType: IrType) =
|
||||
JsIrBuilder.buildCall(target.symbol, returnType).apply {
|
||||
dispatchReceiver = JsIrBuilder.buildGetObjectValue(primitiveClassesObject.defaultType, primitiveClassesObject)
|
||||
dispatchReceiver = JsIrBuilder.buildGetObjectValue(
|
||||
type = reflectionSymbols.primitiveClassesObject.defaultType,
|
||||
classSymbol = reflectionSymbols.primitiveClassesObject
|
||||
)
|
||||
}
|
||||
|
||||
private fun getFinalPrimitiveKClass(returnType: IrType, typeArgument: IrType): IrCall? {
|
||||
@@ -118,7 +123,7 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
}
|
||||
|
||||
private fun callGetKClass(
|
||||
returnType: IrType = context.intrinsics.jsGetKClass.owner.returnType,
|
||||
returnType: IrType = reflectionSymbols.getKClass.owner.returnType,
|
||||
typeArgument: IrType
|
||||
): IrCall {
|
||||
val primitiveKClass =
|
||||
@@ -127,15 +132,15 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
if (primitiveKClass != null)
|
||||
return primitiveKClass
|
||||
|
||||
return JsIrBuilder.buildCall(context.intrinsics.jsGetKClass, returnType, listOf(typeArgument))
|
||||
return JsIrBuilder.buildCall(reflectionSymbols.getKClass, returnType, listOf(typeArgument))
|
||||
.apply {
|
||||
putValueArgument(0, callJsClass(typeArgument))
|
||||
putValueArgument(0, callGetClassByType(typeArgument))
|
||||
}
|
||||
}
|
||||
|
||||
private fun callJsClass(type: IrType) =
|
||||
private fun callGetClassByType(type: IrType) =
|
||||
JsIrBuilder.buildCall(
|
||||
context.intrinsics.jsClass,
|
||||
reflectionSymbols.getClassData,
|
||||
typeArguments = listOf(type),
|
||||
origin = JsLoweredDeclarationOrigin.CLASS_REFERENCE
|
||||
)
|
||||
@@ -157,7 +162,7 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
}
|
||||
|
||||
private fun createDynamicType(): IrExpression {
|
||||
return buildCall(context.intrinsics.createDynamicKType!!)
|
||||
return buildCall(reflectionSymbols.createDynamicKType!!)
|
||||
}
|
||||
|
||||
private fun createSimpleKType(type: IrSimpleType, visitedTypeParams: MutableSet<IrTypeParameter>): IrExpression {
|
||||
@@ -169,15 +174,16 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
// }
|
||||
|
||||
val kClassifier = createKClassifier(classifier, visitedTypeParams)
|
||||
// TODO: Use static array types
|
||||
val arguments = type.arguments.map { createKTypeProjection(it, visitedTypeParams) }.toJsArrayLiteral(
|
||||
context,
|
||||
context.dynamicType,
|
||||
context.dynamicType
|
||||
val arguments = context.createArrayOfExpression(
|
||||
startOffset = UNDEFINED_OFFSET,
|
||||
endOffset = UNDEFINED_OFFSET,
|
||||
arrayElementType = context.reflectionSymbols.kTypeClass.defaultType,
|
||||
arrayElements = type.arguments.map { createKTypeProjection(it, visitedTypeParams) }
|
||||
)
|
||||
|
||||
val isMarkedNullable = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, type.isMarkedNullable())
|
||||
return buildCall(
|
||||
context.intrinsics.createKType!!,
|
||||
reflectionSymbols.createKType!!,
|
||||
kClassifier,
|
||||
arguments,
|
||||
isMarkedNullable
|
||||
@@ -186,13 +192,13 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
|
||||
private fun createKTypeProjection(tp: IrTypeArgument, visitedTypeParams: MutableSet<IrTypeParameter>): IrExpression {
|
||||
if (tp !is IrTypeProjection) {
|
||||
return buildCall(context.intrinsics.getStarKTypeProjection!!)
|
||||
return buildCall(reflectionSymbols.getStarKTypeProjection!!)
|
||||
}
|
||||
|
||||
val factoryName = when (tp.variance) {
|
||||
Variance.INVARIANT -> context.intrinsics.createInvariantKTypeProjection!!
|
||||
Variance.IN_VARIANCE -> context.intrinsics.createContravariantKTypeProjection!!
|
||||
Variance.OUT_VARIANCE -> context.intrinsics.createCovariantKTypeProjection!!
|
||||
Variance.INVARIANT -> reflectionSymbols.createInvariantKTypeProjection!!
|
||||
Variance.IN_VARIANCE -> reflectionSymbols.createContravariantKTypeProjection!!
|
||||
Variance.OUT_VARIANCE -> reflectionSymbols.createCovariantKTypeProjection!!
|
||||
}
|
||||
|
||||
val kType = createKType(tp.type, visitedTypeParams)
|
||||
@@ -213,10 +219,12 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
visitedTypeParams.add(typeParameter)
|
||||
|
||||
val name = JsIrBuilder.buildString(context.irBuiltIns.stringType, typeParameter.name.asString())
|
||||
val upperBounds = typeParameter.superTypes.map { createKType(it, visitedTypeParams) }.toJsArrayLiteral(
|
||||
context,
|
||||
context.dynamicType,
|
||||
context.dynamicType
|
||||
|
||||
val upperBounds = context.createArrayOfExpression(
|
||||
startOffset = UNDEFINED_OFFSET,
|
||||
endOffset = UNDEFINED_OFFSET,
|
||||
arrayElementType = context.reflectionSymbols.kTypeClass.defaultType,
|
||||
arrayElements = typeParameter.superTypes.map { createKType(it, visitedTypeParams) }
|
||||
)
|
||||
|
||||
val variance = when (typeParameter.variance) {
|
||||
@@ -231,7 +239,7 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
// }
|
||||
|
||||
return buildCall(
|
||||
context.intrinsics.createKTypeParameter!!,
|
||||
reflectionSymbols.createKTypeParameter!!,
|
||||
name,
|
||||
upperBounds,
|
||||
variance
|
||||
|
||||
-3
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.getClassRef
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
@@ -15,11 +14,9 @@ import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.types.getClass
|
||||
import org.jetbrains.kotlin.ir.util.getInlineClassBackingField
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import java.lang.IllegalArgumentException
|
||||
|
||||
typealias IrCallTransformer = (IrCall, context: JsGenerationContext) -> JsExpression
|
||||
|
||||
|
||||
@@ -71,19 +71,6 @@ fun IrDeclaration.hasStaticDispatch() = when (this) {
|
||||
else -> true
|
||||
}
|
||||
|
||||
fun List<IrExpression>.toJsArrayLiteral(context: JsCommonBackendContext, arrayType: IrType, elementType: IrType): IrExpression {
|
||||
val irVararg = IrVarargImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, arrayType, elementType, this)
|
||||
|
||||
return IrCallImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, arrayType,
|
||||
context.intrinsics.arrayLiteral,
|
||||
valueArgumentsCount = 1,
|
||||
typeArgumentsCount = 0
|
||||
).apply {
|
||||
putValueArgument(0, irVararg)
|
||||
}
|
||||
}
|
||||
|
||||
val IrValueDeclaration.isDispatchReceiver: Boolean
|
||||
get() {
|
||||
val parent = this.parent
|
||||
|
||||
+2
-32
@@ -24,37 +24,12 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.DescriptorlessExternalPackageFragmentSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrDynamicType
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class WasmIntrinsics(private val context: WasmBackendContext) : Intrinsics {
|
||||
|
||||
override val jsGetKClass: IrSimpleFunctionSymbol get() = context.wasmSymbols.jsGetKClass
|
||||
override val jsGetKClassFromExpression: IrSimpleFunctionSymbol get() = context.wasmSymbols.jsGetKClassFromExpression
|
||||
override val jsClass: IrSimpleFunctionSymbol get() = context.wasmSymbols.jsClass
|
||||
|
||||
override val createKType: IrSimpleFunctionSymbol?
|
||||
get() = TODO("Not yet implemented")
|
||||
override val createDynamicKType: IrSimpleFunctionSymbol?
|
||||
get() = TODO("Not yet implemented")
|
||||
override val createKTypeParameter: IrSimpleFunctionSymbol?
|
||||
get() = TODO("Not yet implemented")
|
||||
override val getStarKTypeProjection: IrSimpleFunctionSymbol?
|
||||
get() = TODO("Not yet implemented")
|
||||
override val createCovariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||
get() = TODO("Not yet implemented")
|
||||
override val createInvariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||
get() = TODO("Not yet implemented")
|
||||
override val createContravariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||
get() = TODO("Not yet implemented")
|
||||
override val arrayLiteral: IrSimpleFunctionSymbol
|
||||
get() = TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
class WasmBackendContext(
|
||||
val module: ModuleDescriptor,
|
||||
override val irBuiltIns: IrBuiltIns,
|
||||
@@ -68,11 +43,6 @@ class WasmBackendContext(
|
||||
override val scriptMode = false
|
||||
override val irFactory: IrFactory = symbolTable.irFactory
|
||||
|
||||
//TODO
|
||||
override val dynamicType: IrDynamicType get() = TODO()
|
||||
override val primitiveClassesObject get() = wasmSymbols.primitiveClassesObject
|
||||
//TODO!!!
|
||||
|
||||
// Place to store declarations excluded from code generation
|
||||
private val excludedDeclarations = mutableMapOf<FqName, IrPackageFragment>()
|
||||
|
||||
@@ -132,6 +102,8 @@ class WasmBackendContext(
|
||||
WasmSharedVariablesManager(this, irBuiltIns, internalPackageFragment)
|
||||
|
||||
val wasmSymbols: WasmSymbols = WasmSymbols(this@WasmBackendContext, symbolTable)
|
||||
override val reflectionSymbols: ReflectionSymbols get() = wasmSymbols.reflectionSymbols
|
||||
|
||||
override val ir = object : Ir<WasmBackendContext>(this, irModuleFragment) {
|
||||
override val symbols: Symbols<WasmBackendContext> = wasmSymbols
|
||||
override fun shouldGenerateHandlerParameterForDefaultBodyFun() = true
|
||||
@@ -199,6 +171,4 @@ class WasmBackendContext(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val intrinsics: Intrinsics = WasmIntrinsics(this)
|
||||
}
|
||||
|
||||
@@ -12,8 +12,7 @@ import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.backend.js.ReflectionSymbols
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
@@ -28,7 +27,6 @@ import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import java.lang.IllegalArgumentException
|
||||
|
||||
class WasmSymbols(
|
||||
@@ -45,11 +43,25 @@ class WasmSymbols(
|
||||
private val kotlinTestPackage: PackageViewDescriptor =
|
||||
context.module.getPackage(FqName("kotlin.test"))
|
||||
|
||||
val jsGetKClass: IrSimpleFunctionSymbol = getInternalFunction("getKClass")
|
||||
val jsGetKClassFromExpression: IrSimpleFunctionSymbol = getInternalFunction("getKClassFromExpression")
|
||||
val jsClass: IrSimpleFunctionSymbol = getInternalFunction("wasmGetTypeInfoData")
|
||||
val wasmTypeInfoData: IrClassSymbol = getInternalClass("TypeInfoData")
|
||||
val primitiveClassesObject = getInternalClass("PrimitiveClasses")
|
||||
internal inner class WasmReflectionSymbols : ReflectionSymbols {
|
||||
override val createKType: IrSimpleFunctionSymbol = getInternalFunction("createKType")
|
||||
override val getClassData: IrSimpleFunctionSymbol = getInternalFunction("wasmGetTypeInfoData")
|
||||
override val getKClass: IrSimpleFunctionSymbol = getInternalFunction("getKClass")
|
||||
override val getKClassFromExpression: IrSimpleFunctionSymbol = getInternalFunction("getKClassFromExpression")
|
||||
override val createDynamicKType: IrSimpleFunctionSymbol get() = error("Dynamic type is not supported by WASM")
|
||||
override val createKTypeParameter: IrSimpleFunctionSymbol = getInternalFunction("createKTypeParameter")
|
||||
override val getStarKTypeProjection = getInternalFunction("getStarKTypeProjection")
|
||||
override val createCovariantKTypeProjection = getInternalFunction("createCovariantKTypeProjection")
|
||||
override val createInvariantKTypeProjection = getInternalFunction("createInvariantKTypeProjection")
|
||||
override val createContravariantKTypeProjection = getInternalFunction("createContravariantKTypeProjection")
|
||||
|
||||
override val primitiveClassesObject = getInternalClass("PrimitiveClasses")
|
||||
override val kTypeClass: IrClassSymbol = getIrClass(FqName("kotlin.reflect.KClass"))
|
||||
|
||||
val wasmTypeInfoData: IrClassSymbol = getInternalClass("TypeInfoData")
|
||||
}
|
||||
|
||||
internal val reflectionSymbols: WasmReflectionSymbols = WasmReflectionSymbols()
|
||||
|
||||
override val throwNullPointerException = getInternalFunction("THROW_NPE")
|
||||
override val throwISE = getInternalFunction("THROW_ISE")
|
||||
@@ -151,7 +163,6 @@ class WasmSymbols(
|
||||
|
||||
val wasmClassId = getInternalFunction("wasmClassId")
|
||||
val wasmInterfaceId = getInternalFunction("wasmInterfaceId")
|
||||
val wasmTypeId = getInternalFunction("wasmTypeId")
|
||||
|
||||
val getVirtualMethodId = getInternalFunction("getVirtualMethodId")
|
||||
val getInterfaceImplId = getInternalFunction("getInterfaceImplId")
|
||||
|
||||
-7
@@ -348,13 +348,6 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV
|
||||
body.buildConstI32Symbol(context.referenceInterfaceId(irInterface.symbol))
|
||||
}
|
||||
|
||||
wasmSymbols.wasmTypeId -> {
|
||||
val type = call.getTypeArgument(0)!!.getClass()
|
||||
?: error("No class given for wasmClassId intrinsic")
|
||||
val id = if (type.isInterface) context.referenceInterfaceId(type.symbol) else context.referenceClassId(type.symbol)
|
||||
body.buildConstI32Symbol(id)
|
||||
}
|
||||
|
||||
wasmSymbols.wasmRefCast -> {
|
||||
val toType = call.getTypeArgument(0)!!
|
||||
generateTypeRTT(toType)
|
||||
|
||||
+5
-1
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.backend.common.ir.isOverridableOrOverrides
|
||||
import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
|
||||
import org.jetbrains.kotlin.backend.wasm.lower.wasmSignature
|
||||
import org.jetbrains.kotlin.backend.wasm.utils.*
|
||||
import org.jetbrains.kotlin.config.AnalysisFlags.allowFullyQualifiedNameInKClass
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
@@ -276,7 +278,9 @@ class DeclarationGenerator(val context: WasmModuleCodegenContext) : IrElementVis
|
||||
private fun binaryDataStruct(classMetadata: ClassMetadata): ConstantDataStruct {
|
||||
val invalidIndex = -1
|
||||
|
||||
val packageName = classMetadata.klass.kotlinFqName.parentOrNull()?.asString() ?: ""
|
||||
val fqnShouldBeEmitted = context.backendContext.configuration.languageVersionSettings.getFlag(allowFullyQualifiedNameInKClass)
|
||||
//TODO("FqName for inner classes could be invalid due to topping it out from outer class")
|
||||
val packageName = if (fqnShouldBeEmitted) classMetadata.klass.kotlinFqName.parentOrNull()?.asString() ?: "" else ""
|
||||
val simpleName = classMetadata.klass.kotlinFqName.shortName().asString()
|
||||
val typeInfo = ConstantDataStruct(
|
||||
"TypeInfo",
|
||||
|
||||
+13
-6
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
|
||||
import org.jetbrains.kotlin.config.AnalysisFlags
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isEqualsInheritedFromAny
|
||||
import org.jetbrains.kotlin.ir.builders.irCall
|
||||
import org.jetbrains.kotlin.ir.builders.irCallConstructor
|
||||
@@ -128,22 +130,27 @@ class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass {
|
||||
val newSymbol = irBuiltins.suspendFunctionN(arity).getSimpleFunction("invoke")!!
|
||||
return irCall(call, newSymbol, argumentsAsReceivers = true)
|
||||
}
|
||||
symbols.jsClass -> {
|
||||
val infoDataCtor = symbols.wasmTypeInfoData.constructors.first()
|
||||
symbols.reflectionSymbols.getClassData -> {
|
||||
val infoDataCtor = symbols.reflectionSymbols.wasmTypeInfoData.constructors.first()
|
||||
val type = call.getTypeArgument(0)!!
|
||||
val isInterface = type.isInterface()
|
||||
val fqName = type.classFqName!!
|
||||
val packageName = fqName.parentOrNull()?.asString() ?: ""
|
||||
val fqnShouldBeEmitted =
|
||||
context.configuration.languageVersionSettings.getFlag(AnalysisFlags.allowFullyQualifiedNameInKClass)
|
||||
val packageName = if (fqnShouldBeEmitted) fqName.parentOrNull()?.asString() ?: "" else ""
|
||||
val typeName = fqName.shortName().asString()
|
||||
|
||||
return with(builder) {
|
||||
val typeId = irCall(symbols.wasmTypeId).also {
|
||||
val wasmIdGetter = if (type.isInterface()) symbols.wasmInterfaceId else symbols.wasmClassId
|
||||
val typeId = irCall(wasmIdGetter).also {
|
||||
it.putTypeArgument(0, type)
|
||||
}
|
||||
|
||||
irCallConstructor(infoDataCtor, emptyList()).also {
|
||||
it.putValueArgument(0, typeId)
|
||||
it.putValueArgument(1, packageName.toIrConst(context.irBuiltIns.stringType))
|
||||
it.putValueArgument(2, typeName.toIrConst(context.irBuiltIns.stringType))
|
||||
it.putValueArgument(1, isInterface.toIrConst(context.irBuiltIns.booleanType))
|
||||
it.putValueArgument(2, packageName.toIrConst(context.irBuiltIns.stringType))
|
||||
it.putValueArgument(3, typeName.toIrConst(context.irBuiltIns.stringType))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -37,6 +37,7 @@ where advanced options include:
|
||||
-Xtyped-arrays Translate primitive arrays to JS typed arrays
|
||||
-Xwasm Use experimental WebAssembly compiler backend
|
||||
-Xwasm-debug-info Add debug info to WebAssembly compiled module
|
||||
-Xwasm-kclass-fqn Enable support for FQ names in KClass
|
||||
-Xwasm-launcher=esm|nodejs Picks flavor for the wasm launcher. Default is ESM.
|
||||
-Xallow-kotlin-package Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info
|
||||
-Xallow-result-return-type Allow compiling code when `kotlin.Result` is used as a return type
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// WASM_MUTE_REASON: TYPEOF
|
||||
// WITH_RUNTIME
|
||||
|
||||
// See KT-37163
|
||||
|
||||
-2
@@ -1,5 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// WASM_MUTE_REASON: TYPEOF
|
||||
// WITH_RUNTIME
|
||||
|
||||
// See KT-37163
|
||||
|
||||
Vendored
-2
@@ -1,5 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// WASM_MUTE_REASON: TYPEOF
|
||||
// WITH_RUNTIME
|
||||
|
||||
// See KT-37163
|
||||
|
||||
+13
@@ -5,10 +5,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.test.services.configuration
|
||||
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag
|
||||
import org.jetbrains.kotlin.config.AnalysisFlags.allowFullyQualifiedNameInKClass
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
||||
import org.jetbrains.kotlin.config.LanguageVersion
|
||||
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives
|
||||
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
|
||||
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.parseAnalysisFlags
|
||||
import org.jetbrains.kotlin.test.services.EnvironmentConfigurator
|
||||
@@ -18,6 +22,15 @@ class CommonEnvironmentConfigurator(testServices: TestServices) : EnvironmentCon
|
||||
override val directiveContainers: List<DirectivesContainer>
|
||||
get() = listOf(ConfigurationDirectives)
|
||||
|
||||
override fun provideAdditionalAnalysisFlags(
|
||||
directives: RegisteredDirectives,
|
||||
languageVersion: LanguageVersion
|
||||
): Map<AnalysisFlag<*>, Any?> {
|
||||
return super.provideAdditionalAnalysisFlags(directives, languageVersion).toMutableMap().also {
|
||||
it[allowFullyQualifiedNameInKClass] = true
|
||||
}
|
||||
}
|
||||
|
||||
override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) {
|
||||
val rawFlags = module.directives[ConfigurationDirectives.KOTLIN_CONFIGURATION_FLAGS]
|
||||
parseAnalysisFlags(rawFlags).forEach { (key, value) ->
|
||||
|
||||
+13
@@ -11,6 +11,9 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag
|
||||
import org.jetbrains.kotlin.config.AnalysisFlags.allowFullyQualifiedNameInKClass
|
||||
import org.jetbrains.kotlin.config.LanguageVersion
|
||||
import org.jetbrains.kotlin.js.config.*
|
||||
import org.jetbrains.kotlin.js.facade.MainCallParameters
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
@@ -30,6 +33,7 @@ import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
||||
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
|
||||
import org.jetbrains.kotlin.test.frontend.classic.moduleDescriptorProvider
|
||||
import org.jetbrains.kotlin.test.model.ArtifactKinds
|
||||
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
|
||||
import org.jetbrains.kotlin.test.model.DependencyDescription
|
||||
import org.jetbrains.kotlin.test.model.DependencyRelation
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
@@ -203,6 +207,15 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
|
||||
regularDependencies.flatMap { modules.single { module -> module.name == it.moduleName }.allTransitiveDependencies() }
|
||||
}
|
||||
|
||||
override fun provideAdditionalAnalysisFlags(
|
||||
directives: RegisteredDirectives,
|
||||
languageVersion: LanguageVersion
|
||||
): Map<AnalysisFlag<*>, Any?> {
|
||||
return super.provideAdditionalAnalysisFlags(directives, languageVersion).toMutableMap().also {
|
||||
it[allowFullyQualifiedNameInKClass] = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) {
|
||||
val registeredDirectives = module.directives
|
||||
val moduleKinds = registeredDirectives[MODULE_KIND]
|
||||
|
||||
+6
-2
@@ -39,8 +39,12 @@ class JsReflectionAPICallChecker(
|
||||
override val isWholeReflectionApiAvailable: Boolean
|
||||
get() = false
|
||||
|
||||
override fun isAllowedReflectionApi(descriptor: CallableDescriptor, containingClass: ClassDescriptor): Boolean {
|
||||
return super.isAllowedReflectionApi(descriptor, containingClass) ||
|
||||
override fun isAllowedReflectionApi(
|
||||
descriptor: CallableDescriptor,
|
||||
containingClass: ClassDescriptor,
|
||||
context: CallCheckerContext
|
||||
): Boolean {
|
||||
return super.isAllowedReflectionApi(descriptor, containingClass, context) ||
|
||||
containingClass.fqNameSafe in ADDITIONAL_ALLOWED_CLASSES ||
|
||||
descriptor.name.asString() == "findAssociatedObject"
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ internal const val TYPE_INFO_ITABLE_PTR_OFFSET = TYPE_INFO_SUPER_TYPE_OFFSET + T
|
||||
internal const val TYPE_INFO_VTABLE_LENGTH_OFFSET = TYPE_INFO_ITABLE_PTR_OFFSET + TYPE_INFO_ELEMENT_SIZE
|
||||
internal const val TYPE_INFO_VTABLE_OFFSET = TYPE_INFO_VTABLE_LENGTH_OFFSET + TYPE_INFO_ELEMENT_SIZE
|
||||
|
||||
internal class TypeInfoData(val typeId: Int, val packageName: String, val typeName: String)
|
||||
internal class TypeInfoData(val typeId: Int, val isInterface: Boolean, val packageName: String, val typeName: String)
|
||||
|
||||
internal fun getTypeInfoTypeDataByPtr(typeInfoPtr: Int): TypeInfoData {
|
||||
val fqNameLength = wasm_i32_load(typeInfoPtr + TYPE_INFO_TYPE_PACKAGE_NAME_LENGTH_OFFSET)
|
||||
@@ -27,7 +27,7 @@ internal fun getTypeInfoTypeDataByPtr(typeInfoPtr: Int): TypeInfoData {
|
||||
val simpleNamePtr = wasm_i32_load(typeInfoPtr + TYPE_INFO_TYPE_SIMPLE_NAME_PRT_OFFSET)
|
||||
val packageName = stringLiteral(fqNameLengthPtr, fqNameLength)
|
||||
val simpleName = stringLiteral(simpleNamePtr, simpleNameLength)
|
||||
return TypeInfoData(typeInfoPtr, packageName, simpleName)
|
||||
return TypeInfoData(typeInfoPtr, isInterface = false, packageName, simpleName)
|
||||
}
|
||||
|
||||
internal fun getSuperTypeId(typeInfoPtr: Int): Int =
|
||||
@@ -83,8 +83,4 @@ internal fun <T> wasmInterfaceId(): Int =
|
||||
|
||||
@ExcludedFromCodegen
|
||||
internal fun <T> wasmGetTypeInfoData(): TypeInfoData =
|
||||
implementedAsIntrinsic
|
||||
|
||||
@ExcludedFromCodegen
|
||||
internal fun <T> wasmTypeId(): Int =
|
||||
implementedAsIntrinsic
|
||||
@@ -6,18 +6,14 @@ package kotlin.reflect.wasm.internal
|
||||
|
||||
import kotlin.reflect.*
|
||||
import kotlin.wasm.internal.TypeInfoData
|
||||
import kotlin.wasm.internal.getInterfaceImplId
|
||||
import kotlin.wasm.internal.getSuperTypeId
|
||||
import kotlin.wasm.internal.isInterface
|
||||
|
||||
internal object NothingKClassImpl : KClass<Nothing> {
|
||||
override val simpleName: String = "Nothing"
|
||||
override val qualifiedName: String get() = "kotlin.Nothing"
|
||||
|
||||
override fun isInstance(value: Any?): Boolean = false
|
||||
|
||||
override fun equals(other: Any?): Boolean = other === this
|
||||
|
||||
override fun hashCode(): Int = -1
|
||||
}
|
||||
|
||||
internal object ErrorKClass : KClass<Nothing> {
|
||||
@@ -25,10 +21,6 @@ internal object ErrorKClass : KClass<Nothing> {
|
||||
override val qualifiedName: String get() = error("Unknown qualifiedName for ErrorKClass")
|
||||
|
||||
override fun isInstance(value: Any?): Boolean = error("Can's check isInstance on ErrorKClass")
|
||||
|
||||
override fun equals(other: Any?): Boolean = other === this
|
||||
|
||||
override fun hashCode(): Int = 0
|
||||
}
|
||||
|
||||
internal class KClassImpl<T : Any>(private val typeData: TypeInfoData) : KClass<T> {
|
||||
@@ -45,11 +37,12 @@ internal class KClassImpl<T : Any>(private val typeData: TypeInfoData) : KClass<
|
||||
return false
|
||||
}
|
||||
|
||||
override fun isInstance(value: Any?): Boolean =
|
||||
value != null && (checkSuperTypeInstance(value) || getInterfaceImplId(value, typeData.typeId) != -1)
|
||||
override fun isInstance(value: Any?): Boolean = value?.let {
|
||||
if (typeData.isInterface) isInterface(it, typeData.typeId) else checkSuperTypeInstance(it)
|
||||
} ?: false
|
||||
|
||||
override fun equals(other: Any?): Boolean =
|
||||
(this === other) || (other is KClassImpl<*> && other.typeInfo == typeData.typeId)
|
||||
(this === other) || (other is KClassImpl<*> && other.typeData.isInterface == typeData.isInterface && other.typeData.typeId == typeData.typeId)
|
||||
|
||||
override fun hashCode(): Int = typeData.typeId
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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 kotlin.wasm.internal
|
||||
|
||||
import kotlin.reflect.*
|
||||
|
||||
internal class KTypeImpl(
|
||||
override val classifier: KClassifier?,
|
||||
override val arguments: List<KTypeProjection>,
|
||||
override val isMarkedNullable: Boolean
|
||||
) : KType
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* 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 kotlin.wasm.internal
|
||||
|
||||
import kotlin.reflect.*
|
||||
|
||||
internal data class KTypeParameterImpl(
|
||||
override val name: String,
|
||||
override val upperBounds: List<KType>,
|
||||
override val variance: KVariance,
|
||||
override val isReified: Boolean
|
||||
) : KTypeParameter {
|
||||
override fun toString(): String = name
|
||||
}
|
||||
@@ -14,6 +14,7 @@ internal object PrimitiveClasses {
|
||||
|
||||
val anyClass = wasmGetKClass<Any>()
|
||||
val numberClass = wasmGetKClass<Number>()
|
||||
val longClass = wasmGetKClass<Long>()
|
||||
val booleanClass = wasmGetKClass<Boolean>()
|
||||
val byteClass = wasmGetKClass<Byte>()
|
||||
val shortClass = wasmGetKClass<Short>()
|
||||
|
||||
@@ -9,21 +9,8 @@ package kotlin.wasm.internal
|
||||
import kotlin.reflect.*
|
||||
import kotlin.reflect.wasm.internal.*
|
||||
|
||||
internal fun <T : Any> getKClass(typeInfoData: TypeInfoData): KClass<T> {
|
||||
// return if (js("Array").isArray(jClass)) {
|
||||
// getKClassM(jClass.unsafeCast<Array<JsClass<T>>>())
|
||||
// } else {
|
||||
// getKClass1(jClass.unsafeCast<JsClass<T>>())
|
||||
// }
|
||||
|
||||
return getKClass1(typeInfoData)
|
||||
}
|
||||
|
||||
internal fun <T : Any> getKClassM(jClasses: Array<TypeInfoData>): KClass<T> = when (jClasses.size) {
|
||||
1 -> getKClass1(jClasses[0])
|
||||
0 -> NothingKClassImpl as KClass<T>
|
||||
else -> ErrorKClass as KClass<T>
|
||||
}
|
||||
internal fun <T : Any> getKClass(typeInfoData: TypeInfoData): KClass<T> =
|
||||
KClassImpl(typeInfoData)
|
||||
|
||||
internal fun <T : Any> getKClassFromExpression(e: T): KClass<T> =
|
||||
when (e) {
|
||||
@@ -33,6 +20,7 @@ internal fun <T : Any> getKClassFromExpression(e: T): KClass<T> =
|
||||
is Float -> PrimitiveClasses.floatClass
|
||||
is Boolean -> PrimitiveClasses.booleanClass
|
||||
is Double -> PrimitiveClasses.doubleClass
|
||||
is Long -> PrimitiveClasses.longClass
|
||||
is Number -> PrimitiveClasses.numberClass
|
||||
|
||||
is BooleanArray -> PrimitiveClasses.booleanArrayClass
|
||||
@@ -45,17 +33,33 @@ internal fun <T : Any> getKClassFromExpression(e: T): KClass<T> =
|
||||
is DoubleArray -> PrimitiveClasses.doubleArrayClass
|
||||
is KClass<*> -> KClass::class
|
||||
is Array<*> -> PrimitiveClasses.arrayClass
|
||||
|
||||
is Function<*> -> PrimitiveClasses.functionClass(0) //TODO
|
||||
else -> {
|
||||
getKClass1(getTypeInfoTypeDataByPtr(e.typeInfo))
|
||||
}
|
||||
else -> getKClass(getTypeInfoTypeDataByPtr(e.typeInfo))
|
||||
} as KClass<T>
|
||||
|
||||
internal fun <T : Any> getKClass1(infoData: TypeInfoData): KClass<T> {
|
||||
return KClassImpl(infoData)
|
||||
}
|
||||
|
||||
@Suppress("REIFIED_TYPE_PARAMETER_NO_INLINE")
|
||||
internal inline fun <reified T : Any> wasmGetKClass(): KClass<T> =
|
||||
KClassImpl(wasmGetTypeInfoData<T>())
|
||||
|
||||
internal fun createKType(classifier: KClassifier, arguments: Array<KTypeProjection>, isMarkedNullable: Boolean): KType =
|
||||
KTypeImpl(classifier, arguments.asList(), isMarkedNullable)
|
||||
|
||||
internal fun createKTypeParameter(name: String, upperBounds: Array<KType>, variance: String): KTypeParameter {
|
||||
val kVariance = when (variance) {
|
||||
"in" -> KVariance.IN
|
||||
"out" -> KVariance.OUT
|
||||
else -> KVariance.INVARIANT
|
||||
}
|
||||
return KTypeParameterImpl(name, upperBounds.asList(), kVariance, false)
|
||||
}
|
||||
|
||||
internal fun getStarKTypeProjection(): KTypeProjection =
|
||||
KTypeProjection.STAR
|
||||
|
||||
internal fun createCovariantKTypeProjection(type: KType): KTypeProjection =
|
||||
KTypeProjection.covariant(type)
|
||||
|
||||
internal fun createInvariantKTypeProjection(type: KType): KTypeProjection =
|
||||
KTypeProjection.invariant(type)
|
||||
|
||||
internal fun createContravariantKTypeProjection(type: KType): KTypeProjection =
|
||||
KTypeProjection.contravariant(type)
|
||||
|
||||
Reference in New Issue
Block a user