Do not use KotlinTypeMapper in generateTypeOf inline intrinsic
Make ReifiedTypeInliner and related classes generic over the KotlinTypeMarker subtype (KotlinType or IrType), add a typeSystem to get arguments/nullability and other properties of types regardless of their representation, but still fall back to KotlinType when generating the actual bytecode of other intrinsics (as/is)
This commit is contained in:
@@ -77,10 +77,8 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*;
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.SimpleType;
|
||||
import org.jetbrains.kotlin.types.TypeProjection;
|
||||
import org.jetbrains.kotlin.types.TypeUtils;
|
||||
import org.jetbrains.kotlin.types.*;
|
||||
import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContextImpl;
|
||||
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS;
|
||||
import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
@@ -125,6 +123,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
private final TailRecursionCodegen tailRecursionCodegen;
|
||||
public final CallGenerator defaultCallGenerator = new CallGenerator.DefaultCallGenerator(this);
|
||||
private final SwitchCodegenProvider switchCodegenProvider;
|
||||
public final TypeSystemCommonBackendContext typeSystem;
|
||||
|
||||
private final Stack<BlockStackElement> blockStackElements = new Stack<>();
|
||||
|
||||
@@ -157,6 +156,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
this.parentCodegen = parentCodegen;
|
||||
this.tailRecursionCodegen = new TailRecursionCodegen(context, this, this.v, state);
|
||||
this.switchCodegenProvider = new SwitchCodegenProvider(this);
|
||||
this.typeSystem = new ClassicTypeSystemContextImpl(state.getModule().getBuiltIns());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -2622,7 +2622,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
private CallGenerator getOrCreateCallGenerator(
|
||||
@NotNull CallableDescriptor descriptor,
|
||||
@Nullable KtElement callElement,
|
||||
@Nullable TypeParameterMappings typeParameterMappings,
|
||||
@Nullable TypeParameterMappings<KotlinType> typeParameterMappings,
|
||||
boolean isDefaultCompilation
|
||||
) {
|
||||
if (callElement == null) return defaultCallGenerator;
|
||||
@@ -2672,7 +2672,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
CallGenerator getOrCreateCallGenerator(@NotNull ResolvedCall<?> resolvedCall, @NotNull CallableDescriptor descriptor) {
|
||||
Map<TypeParameterDescriptor, KotlinType> typeArguments = getTypeArgumentsForResolvedCall(resolvedCall, descriptor);
|
||||
|
||||
TypeParameterMappings mappings = new TypeParameterMappings();
|
||||
TypeParameterMappings<KotlinType> mappings = new TypeParameterMappings<>();
|
||||
for (Map.Entry<TypeParameterDescriptor, KotlinType> entry : typeArguments.entrySet()) {
|
||||
TypeParameterDescriptor key = entry.getKey();
|
||||
KotlinType type = entry.getValue();
|
||||
|
||||
@@ -47,8 +47,9 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
protected val functionDescriptor: FunctionDescriptor,
|
||||
private val methodOwner: Type,
|
||||
protected val jvmSignature: JvmMethodSignature,
|
||||
private val typeParameterMappings: TypeParameterMappings,
|
||||
protected val sourceCompiler: SourceCompilerForInline
|
||||
private val typeParameterMappings: TypeParameterMappings<*>,
|
||||
protected val sourceCompiler: SourceCompilerForInline,
|
||||
private val reifiedTypeInliner: ReifiedTypeInliner<*>
|
||||
) {
|
||||
init {
|
||||
assert(InlineUtil.isInline(functionDescriptor)) {
|
||||
@@ -59,13 +60,8 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
// TODO: implement AS_FUNCTION inline strategy
|
||||
private val asFunctionInline = false
|
||||
|
||||
protected val typeMapper = state.typeMapper
|
||||
|
||||
private val initialFrameSize = codegen.frameMap.currentSize
|
||||
|
||||
private val reifiedTypeInliner =
|
||||
ReifiedTypeInliner(typeParameterMappings, state.typeMapper, state.languageVersionSettings)
|
||||
|
||||
private val isSameModule: Boolean
|
||||
|
||||
protected val invocationParamBuilder = ParametersBuilder.newBuilder()
|
||||
|
||||
@@ -14,8 +14,8 @@ class RootInliningContext(
|
||||
nameGenerator: NameGenerator,
|
||||
val sourceCompilerForInline: SourceCompilerForInline,
|
||||
override val callSiteInfo: InlineCallSiteInfo,
|
||||
val inlineMethodReifier: ReifiedTypeInliner,
|
||||
typeParameterMappings: TypeParameterMappings
|
||||
val inlineMethodReifier: ReifiedTypeInliner<*>,
|
||||
typeParameterMappings: TypeParameterMappings<*>
|
||||
) : InliningContext(
|
||||
null, expressionMap, state, nameGenerator, TypeRemapper.createRoot(typeParameterMappings), null, false
|
||||
)
|
||||
|
||||
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.OwnerKind
|
||||
import org.jetbrains.kotlin.codegen.PropertyReferenceCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure
|
||||
@@ -32,7 +31,6 @@ import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
interface FunctionalArgument
|
||||
@@ -51,7 +49,7 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : FunctionalArgu
|
||||
|
||||
lateinit var node: SMAPAndMethodNode
|
||||
|
||||
abstract fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner)
|
||||
abstract fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner<*>)
|
||||
|
||||
open val hasDispatchReceiver = true
|
||||
|
||||
@@ -108,7 +106,7 @@ class DefaultLambda(
|
||||
var originalBoundReceiverType: Type? = null
|
||||
private set
|
||||
|
||||
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner) {
|
||||
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner<*>) {
|
||||
val classReader = buildClassReaderByInternalName(sourceCompiler.state, lambdaClassType.internalName)
|
||||
var isPropertyReference = false
|
||||
var isFunctionReference = false
|
||||
@@ -189,7 +187,7 @@ internal fun Type.boxReceiverForBoundReference(kotlinType: KotlinType, typeMappe
|
||||
AsmUtil.boxType(this, kotlinType, typeMapper)
|
||||
|
||||
abstract class ExpressionLambda(isCrossInline: Boolean) : LambdaInfo(isCrossInline) {
|
||||
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner) {
|
||||
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner<*>) {
|
||||
node = sourceCompiler.generateLambdaBody(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,10 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class PsiInlineCodegen(
|
||||
codegen: ExpressionCodegen,
|
||||
@@ -32,10 +34,17 @@ class PsiInlineCodegen(
|
||||
function: FunctionDescriptor,
|
||||
methodOwner: Type,
|
||||
signature: JvmMethodSignature,
|
||||
typeParameterMappings: TypeParameterMappings,
|
||||
typeParameterMappings: TypeParameterMappings<KotlinType>,
|
||||
sourceCompiler: SourceCompilerForInline
|
||||
) : InlineCodegen<ExpressionCodegen>(
|
||||
codegen, state, function, methodOwner, signature, typeParameterMappings, sourceCompiler
|
||||
codegen, state, function, methodOwner, signature, typeParameterMappings, sourceCompiler,
|
||||
ReifiedTypeInliner(typeParameterMappings, object : ReifiedTypeInliner.IntrinsicsSupport<KotlinType> {
|
||||
override fun putClassInstance(v: InstructionAdapter, type: KotlinType) {
|
||||
AsmUtil.putJavaLangClassInstance(v, state.typeMapper.mapType(type), type, state.typeMapper)
|
||||
}
|
||||
|
||||
override fun toKotlinType(type: KotlinType): KotlinType = type
|
||||
}, codegen.typeSystem, state.languageVersionSettings)
|
||||
), CallGenerator {
|
||||
|
||||
override fun generateAssertFieldIfNeeded(info: RootInliningContext) {
|
||||
@@ -154,7 +163,7 @@ class PsiInlineCodegen(
|
||||
assert(isInlinableParameterExpression(ktLambda)) { "Couldn't find inline expression in ${expression.text}" }
|
||||
|
||||
return PsiExpressionLambda(
|
||||
ktLambda!!, typeMapper, state.languageVersionSettings,
|
||||
ktLambda!!, state.typeMapper, state.languageVersionSettings,
|
||||
parameter.isCrossinline, getBoundCallableReferenceReceiver(expression) != null
|
||||
).also { lambda ->
|
||||
val closureInfo = invocationParamBuilder.addNextValueParameter(type, true, null, parameter.index)
|
||||
|
||||
@@ -20,15 +20,13 @@ import org.jetbrains.kotlin.codegen.generateAsCast
|
||||
import org.jetbrains.kotlin.codegen.generateIsCheck
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.intConstant
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -37,37 +35,23 @@ import org.jetbrains.org.objectweb.asm.tree.*
|
||||
import kotlin.math.max
|
||||
|
||||
class ReificationArgument(
|
||||
val parameterName: String, val nullable: Boolean, private val arrayDepth: Int
|
||||
val parameterName: String, val nullable: Boolean, val arrayDepth: Int
|
||||
) {
|
||||
fun asString() = "[".repeat(arrayDepth) + parameterName + (if (nullable) "?" else "")
|
||||
fun combine(replacement: ReificationArgument) =
|
||||
fun asString(): String =
|
||||
"[".repeat(arrayDepth) + parameterName + (if (nullable) "?" else "")
|
||||
|
||||
fun combine(replacement: ReificationArgument): ReificationArgument =
|
||||
ReificationArgument(
|
||||
replacement.parameterName,
|
||||
this.nullable || (replacement.nullable && this.arrayDepth == 0),
|
||||
this.arrayDepth + replacement.arrayDepth
|
||||
)
|
||||
|
||||
fun reify(replacementAsmType: Type, kotlinType: KotlinType) =
|
||||
Pair(
|
||||
Type.getType("[".repeat(arrayDepth) + replacementAsmType),
|
||||
TypeUtils.makeNullableIfNeeded(kotlinType.arrayOf(arrayDepth), nullable)
|
||||
)
|
||||
|
||||
private fun KotlinType.arrayOf(arrayDepth: Int): KotlinType {
|
||||
val builtins = this.builtIns
|
||||
var currentType = this
|
||||
|
||||
repeat(arrayDepth) {
|
||||
currentType = builtins.getArrayType(Variance.INVARIANT, currentType)
|
||||
}
|
||||
|
||||
return currentType
|
||||
}
|
||||
}
|
||||
|
||||
class ReifiedTypeInliner(
|
||||
private val parametersMapping: TypeParameterMappings?,
|
||||
private val typeMapper: KotlinTypeMapper,
|
||||
class ReifiedTypeInliner<KT : KotlinTypeMarker>(
|
||||
private val parametersMapping: TypeParameterMappings<KT>?,
|
||||
private val intrinsicsSupport: IntrinsicsSupport<KT>,
|
||||
private val typeSystem: TypeSystemCommonBackendContext,
|
||||
private val languageVersionSettings: LanguageVersionSettings
|
||||
) {
|
||||
enum class OperationKind {
|
||||
@@ -76,6 +60,12 @@ class ReifiedTypeInliner(
|
||||
val id: Int get() = ordinal
|
||||
}
|
||||
|
||||
interface IntrinsicsSupport<KT : KotlinTypeMarker> {
|
||||
fun putClassInstance(v: InstructionAdapter, type: KT)
|
||||
|
||||
fun toKotlinType(type: KT): KotlinType
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val REIFIED_OPERATION_MARKER_METHOD_NAME = "reifiedOperationMarker"
|
||||
const val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME = "needClassReification"
|
||||
@@ -112,14 +102,17 @@ class ReifiedTypeInliner(
|
||||
}
|
||||
|
||||
fun putReifiedOperationMarkerIfNeeded(
|
||||
typeParameter: TypeParameterDescriptor,
|
||||
typeParameter: TypeParameterMarker,
|
||||
isNullable: Boolean,
|
||||
operationKind: OperationKind,
|
||||
v: InstructionAdapter
|
||||
v: InstructionAdapter,
|
||||
typeSystem: TypeSystemCommonBackendContext
|
||||
) {
|
||||
if (typeParameter.isReified) {
|
||||
val argument = ReificationArgument(typeParameter.name.asString(), isNullable, 0)
|
||||
putReifiedOperationMarker(operationKind, argument, v)
|
||||
with(typeSystem) {
|
||||
if (typeParameter.isReified()) {
|
||||
val argument = ReificationArgument(typeParameter.getName().asString(), isNullable, 0)
|
||||
putReifiedOperationMarker(operationKind, argument, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,7 +158,9 @@ class ReifiedTypeInliner(
|
||||
// process* methods return false if marker should be reified further
|
||||
// or it's invalid (may be emitted explicitly in code)
|
||||
// they return true if instruction is reified and marker can be deleted
|
||||
val (asmType, kotlinType) = reificationArgument.reify(mapping.asmType, mapping.type)
|
||||
val (asmType, type) = reify(reificationArgument, mapping.asmType, mapping.type)
|
||||
|
||||
val kotlinType = intrinsicsSupport.toKotlinType(type)
|
||||
|
||||
if (when (operationKind) {
|
||||
OperationKind.NEW_ARRAY -> processNewArray(insn, asmType)
|
||||
@@ -174,7 +169,7 @@ class ReifiedTypeInliner(
|
||||
OperationKind.IS -> processIs(insn, instructions, kotlinType, asmType)
|
||||
OperationKind.JAVA_CLASS -> processJavaClass(insn, asmType)
|
||||
OperationKind.ENUM_REIFIED -> processSpecialEnumFunction(insn, instructions, asmType)
|
||||
OperationKind.TYPE_OF -> processTypeOf(insn, instructions, kotlinType)
|
||||
OperationKind.TYPE_OF -> processTypeOf(insn, instructions, type)
|
||||
}
|
||||
) {
|
||||
instructions.remove(insn.previous.previous!!) // PUSH operation ID
|
||||
@@ -190,6 +185,27 @@ class ReifiedTypeInliner(
|
||||
}
|
||||
}
|
||||
|
||||
private fun reify(argument: ReificationArgument, replacementAsmType: Type, type: KT): Pair<Type, KT> =
|
||||
with(typeSystem) {
|
||||
val arrayType = type.arrayOf(argument.arrayDepth)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
Pair(
|
||||
Type.getType("[".repeat(argument.arrayDepth) + replacementAsmType),
|
||||
(if (argument.nullable) arrayType.makeNullable() else arrayType) as KT
|
||||
)
|
||||
}
|
||||
|
||||
private fun KotlinTypeMarker.arrayOf(arrayDepth: Int): KotlinTypeMarker {
|
||||
var currentType = this
|
||||
|
||||
repeat(arrayDepth) {
|
||||
currentType = typeSystem.arrayType(currentType)
|
||||
}
|
||||
|
||||
return currentType
|
||||
}
|
||||
|
||||
|
||||
private fun processNewArray(insn: MethodInsnNode, parameter: Type) =
|
||||
processNextTypeInsn(insn, parameter, Opcodes.ANEWARRAY)
|
||||
|
||||
@@ -236,10 +252,10 @@ class ReifiedTypeInliner(
|
||||
private fun processTypeOf(
|
||||
insn: MethodInsnNode,
|
||||
instructions: InsnList,
|
||||
kotlinType: KotlinType
|
||||
type: KT
|
||||
) = rewriteNextTypeInsn(insn, Opcodes.ACONST_NULL) { stubConstNull: AbstractInsnNode ->
|
||||
val newMethodNode = MethodNode(Opcodes.API_VERSION)
|
||||
val stackSize = generateTypeOf(InstructionAdapter(newMethodNode), kotlinType, typeMapper)
|
||||
val stackSize = typeSystem.generateTypeOf(InstructionAdapter(newMethodNode), type, intrinsicsSupport)
|
||||
|
||||
instructions.insert(insn, newMethodNode.instructions)
|
||||
instructions.remove(stubConstNull)
|
||||
@@ -316,38 +332,33 @@ val MethodInsnNode.operationKind: ReifiedTypeInliner.OperationKind?
|
||||
ReifiedTypeInliner.OperationKind.values().getOrNull(it)
|
||||
}
|
||||
|
||||
class TypeParameterMappings() {
|
||||
private val mappingsByName = hashMapOf<String, TypeParameterMapping>()
|
||||
class TypeParameterMappings<KT : KotlinTypeMarker> {
|
||||
private val mappingsByName = hashMapOf<String, TypeParameterMapping<KT>>()
|
||||
|
||||
fun addParameterMappingToType(name: String, type: KotlinType, asmType: Type, signature: String, isReified: Boolean) {
|
||||
fun addParameterMappingToType(name: String, type: KT, asmType: Type, signature: String, isReified: Boolean) {
|
||||
mappingsByName[name] = TypeParameterMapping(
|
||||
name, type, asmType, reificationArgument = null, signature = signature, isReified = isReified
|
||||
)
|
||||
}
|
||||
|
||||
fun addParameterMappingForFurtherReification(
|
||||
name: String,
|
||||
type: KotlinType,
|
||||
reificationArgument: ReificationArgument,
|
||||
isReified: Boolean
|
||||
) {
|
||||
fun addParameterMappingForFurtherReification(name: String, type: KT, reificationArgument: ReificationArgument, isReified: Boolean) {
|
||||
mappingsByName[name] = TypeParameterMapping(
|
||||
name, type, asmType = null, reificationArgument = reificationArgument, signature = null, isReified = isReified
|
||||
)
|
||||
}
|
||||
|
||||
operator fun get(name: String): TypeParameterMapping? = mappingsByName[name]
|
||||
operator fun get(name: String): TypeParameterMapping<KT>? = mappingsByName[name]
|
||||
|
||||
fun hasReifiedParameters() = mappingsByName.values.any { it.isReified }
|
||||
|
||||
internal inline fun forEach(l: (TypeParameterMapping) -> Unit) {
|
||||
internal inline fun forEach(l: (TypeParameterMapping<KT>) -> Unit) {
|
||||
mappingsByName.values.forEach(l)
|
||||
}
|
||||
}
|
||||
|
||||
class TypeParameterMapping(
|
||||
class TypeParameterMapping<KT : KotlinTypeMarker>(
|
||||
val name: String,
|
||||
val type: KotlinType,
|
||||
val type: KT,
|
||||
val asmType: Type?,
|
||||
val reificationArgument: ReificationArgument?,
|
||||
val signature: String?,
|
||||
|
||||
@@ -52,7 +52,7 @@ class TypeRemapper private constructor(
|
||||
typeParametersMapping[name] = TypeParameter(name, name, false, null)
|
||||
}
|
||||
|
||||
fun registerTypeParameter(mapping: TypeParameterMapping) {
|
||||
fun registerTypeParameter(mapping: TypeParameterMapping<*>) {
|
||||
typeParametersMapping[mapping.name] = TypeParameter(
|
||||
mapping.name, mapping.reificationArgument?.parameterName, mapping.isReified, mapping.signature
|
||||
)
|
||||
@@ -64,8 +64,8 @@ class TypeRemapper private constructor(
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun createRoot(formalTypeParameters: TypeParameterMappings?): TypeRemapper {
|
||||
return TypeRemapper(HashMap<String, String?>()).apply {
|
||||
fun createRoot(formalTypeParameters: TypeParameterMappings<*>?): TypeRemapper {
|
||||
return TypeRemapper(HashMap()).apply {
|
||||
formalTypeParameters?.forEach {
|
||||
registerTypeParameter(it)
|
||||
}
|
||||
|
||||
@@ -23,9 +23,12 @@ import org.jetbrains.kotlin.resolve.calls.checkers.TypeOfChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.isBuiltInCoroutineContext
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeProjection
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||
import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContextImpl
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeArgumentMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeVariance
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
@@ -38,11 +41,15 @@ internal fun generateInlineIntrinsic(
|
||||
): MethodNode? {
|
||||
val languageVersionSettings = state.languageVersionSettings
|
||||
val typeMapper = state.typeMapper
|
||||
|
||||
// TODO
|
||||
val typeSystem = ClassicTypeSystemContextImpl(state.module.builtIns)
|
||||
|
||||
return when {
|
||||
isSpecialEnumMethod(descriptor) ->
|
||||
createSpecialEnumMethodBody(descriptor.name.asString(), typeArguments!!.keys.single(), typeMapper)
|
||||
createSpecialEnumMethodBody(descriptor.name.asString(), typeArguments!!.keys.single(), typeMapper, typeSystem)
|
||||
TypeOfChecker.isTypeOf(descriptor) ->
|
||||
createTypeOfMethodBody(typeArguments!!.keys.single())
|
||||
typeSystem.createTypeOfMethodBody(typeArguments!!.keys.single())
|
||||
descriptor.isBuiltInIntercepted(languageVersionSettings) ->
|
||||
createMethodNodeForIntercepted(descriptor, typeMapper, languageVersionSettings)
|
||||
descriptor.isBuiltInCoroutineContext(languageVersionSettings) ->
|
||||
@@ -69,13 +76,15 @@ private fun isSpecialEnumMethod(descriptor: FunctionDescriptor): Boolean {
|
||||
(name == "enumValueOf" && parameters.size == 1 && KotlinBuiltIns.isString(parameters[0].type))
|
||||
}
|
||||
|
||||
private fun createSpecialEnumMethodBody(name: String, typeParameter: TypeParameterDescriptor, typeMapper: KotlinTypeMapper): MethodNode {
|
||||
private fun createSpecialEnumMethodBody(
|
||||
name: String, typeParameter: TypeParameterDescriptor, typeMapper: KotlinTypeMapper, typeSystem: TypeSystemCommonBackendContext
|
||||
): MethodNode {
|
||||
val isValueOf = "enumValueOf" == name
|
||||
val invokeType = typeMapper.mapType(typeParameter.defaultType)
|
||||
val desc = getSpecialEnumFunDescriptor(invokeType, isValueOf)
|
||||
val node = MethodNode(Opcodes.API_VERSION, Opcodes.ACC_STATIC, "fake", desc, null, null)
|
||||
ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded(
|
||||
typeParameter, false, ReifiedTypeInliner.OperationKind.ENUM_REIFIED, InstructionAdapter(node)
|
||||
typeParameter, false, ReifiedTypeInliner.OperationKind.ENUM_REIFIED, InstructionAdapter(node), typeSystem
|
||||
)
|
||||
if (isValueOf) {
|
||||
node.visitInsn(Opcodes.ACONST_NULL)
|
||||
@@ -98,7 +107,7 @@ internal fun getSpecialEnumFunDescriptor(type: Type, isValueOf: Boolean): String
|
||||
if (isValueOf) Type.getMethodDescriptor(type, JAVA_STRING_TYPE)
|
||||
else Type.getMethodDescriptor(AsmUtil.getArrayType(type))
|
||||
|
||||
private fun createTypeOfMethodBody(typeParameter: TypeParameterDescriptor): MethodNode {
|
||||
private fun TypeSystemCommonBackendContext.createTypeOfMethodBody(typeParameter: TypeParameterMarker): MethodNode {
|
||||
val node = MethodNode(Opcodes.API_VERSION, Opcodes.ACC_STATIC, "fake", Type.getMethodDescriptor(K_TYPE), null, null)
|
||||
val v = InstructionAdapter(node)
|
||||
|
||||
@@ -110,33 +119,36 @@ private fun createTypeOfMethodBody(typeParameter: TypeParameterDescriptor): Meth
|
||||
return node
|
||||
}
|
||||
|
||||
private fun putTypeOfReifiedTypeParameter(v: InstructionAdapter, typeParameter: TypeParameterDescriptor, isNullable: Boolean) {
|
||||
ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded(typeParameter, isNullable, ReifiedTypeInliner.OperationKind.TYPE_OF, v)
|
||||
private fun TypeSystemCommonBackendContext.putTypeOfReifiedTypeParameter(
|
||||
v: InstructionAdapter, typeParameter: TypeParameterMarker, isNullable: Boolean
|
||||
) {
|
||||
ReifiedTypeInliner.putReifiedOperationMarkerIfNeeded(typeParameter, isNullable, ReifiedTypeInliner.OperationKind.TYPE_OF, v, this)
|
||||
v.aconst(null)
|
||||
}
|
||||
|
||||
// Returns some upper bound on maximum stack size
|
||||
internal fun generateTypeOf(v: InstructionAdapter, kotlinType: KotlinType, typeMapper: KotlinTypeMapper): Int {
|
||||
val asmType = typeMapper.mapType(kotlinType)
|
||||
AsmUtil.putJavaLangClassInstance(v, asmType, kotlinType, typeMapper)
|
||||
internal fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateTypeOf(
|
||||
v: InstructionAdapter, type: KT, intrinsicsSupport: ReifiedTypeInliner.IntrinsicsSupport<KT>
|
||||
): Int {
|
||||
intrinsicsSupport.putClassInstance(v, type)
|
||||
|
||||
val arguments = kotlinType.arguments
|
||||
val useArray = arguments.size >= 3
|
||||
val argumentsSize = type.argumentsCount()
|
||||
val useArray = argumentsSize >= 3
|
||||
|
||||
if (useArray) {
|
||||
v.iconst(arguments.size)
|
||||
v.iconst(argumentsSize)
|
||||
v.newarray(K_TYPE_PROJECTION)
|
||||
}
|
||||
|
||||
var maxStackSize = 3
|
||||
|
||||
for (i in 0 until arguments.size) {
|
||||
for (i in 0 until argumentsSize) {
|
||||
if (useArray) {
|
||||
v.dup()
|
||||
v.iconst(i)
|
||||
}
|
||||
|
||||
val stackSize = doGenerateTypeProjection(v, arguments[i], typeMapper)
|
||||
val stackSize = doGenerateTypeProjection(v, type.getArgument(i), intrinsicsSupport)
|
||||
maxStackSize = maxOf(maxStackSize, stackSize + i + 5)
|
||||
|
||||
if (useArray) {
|
||||
@@ -144,9 +156,9 @@ internal fun generateTypeOf(v: InstructionAdapter, kotlinType: KotlinType, typeM
|
||||
}
|
||||
}
|
||||
|
||||
val methodName = if (kotlinType.isMarkedNullable) "nullableTypeOf" else "typeOf"
|
||||
val methodName = if (type.isMarkedNullable()) "nullableTypeOf" else "typeOf"
|
||||
|
||||
val projections = when (arguments.size) {
|
||||
val projections = when (argumentsSize) {
|
||||
0 -> emptyArray()
|
||||
1 -> arrayOf(K_TYPE_PROJECTION)
|
||||
2 -> arrayOf(K_TYPE_PROJECTION, K_TYPE_PROJECTION)
|
||||
@@ -159,37 +171,39 @@ internal fun generateTypeOf(v: InstructionAdapter, kotlinType: KotlinType, typeM
|
||||
return maxStackSize
|
||||
}
|
||||
|
||||
private fun doGenerateTypeProjection(
|
||||
private fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.doGenerateTypeProjection(
|
||||
v: InstructionAdapter,
|
||||
projection: TypeProjection,
|
||||
typeMapper: KotlinTypeMapper
|
||||
projection: TypeArgumentMarker,
|
||||
intrinsicsSupport: ReifiedTypeInliner.IntrinsicsSupport<KT>
|
||||
): Int {
|
||||
// KTypeProjection members could be static, see KT-30083 and KT-30084
|
||||
v.getstatic(K_TYPE_PROJECTION.internalName, "Companion", K_TYPE_PROJECTION_COMPANION.descriptor)
|
||||
|
||||
if (projection.isStarProjection) {
|
||||
if (projection.isStarProjection()) {
|
||||
v.invokevirtual(K_TYPE_PROJECTION_COMPANION.internalName, "getSTAR", Type.getMethodDescriptor(K_TYPE_PROJECTION), false)
|
||||
return 1
|
||||
}
|
||||
|
||||
val type = projection.type
|
||||
val descriptor = type.constructor.declarationDescriptor
|
||||
val stackSize = if (descriptor is TypeParameterDescriptor) {
|
||||
if (descriptor.isReified) {
|
||||
putTypeOfReifiedTypeParameter(v, descriptor, type.isMarkedNullable)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val type = projection.getType() as KT
|
||||
val typeParameterClassifier = type.typeConstructor().getTypeParameterClassifier()
|
||||
val stackSize = if (typeParameterClassifier != null) {
|
||||
if (typeParameterClassifier.isReified()) {
|
||||
putTypeOfReifiedTypeParameter(v, typeParameterClassifier, type.isMarkedNullable())
|
||||
2
|
||||
} else {
|
||||
// TODO: support non-reified type parameters in typeOf
|
||||
generateTypeOf(v, type.builtIns.nullableAnyType, typeMapper)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
generateTypeOf(v, nullableAnyType() as KT, intrinsicsSupport)
|
||||
}
|
||||
} else {
|
||||
generateTypeOf(v, type, typeMapper)
|
||||
generateTypeOf(v, type, intrinsicsSupport)
|
||||
}
|
||||
|
||||
val methodName = when (projection.projectionKind) {
|
||||
Variance.INVARIANT -> "invariant"
|
||||
Variance.IN_VARIANCE -> "contravariant"
|
||||
Variance.OUT_VARIANCE -> "covariant"
|
||||
val methodName = when (projection.getVariance()) {
|
||||
TypeVariance.INV -> "invariant"
|
||||
TypeVariance.IN -> "contravariant"
|
||||
TypeVariance.OUT -> "covariant"
|
||||
}
|
||||
v.invokevirtual(K_TYPE_PROJECTION_COMPANION.internalName, methodName, Type.getMethodDescriptor(K_TYPE_PROJECTION, K_TYPE), false)
|
||||
|
||||
|
||||
@@ -431,6 +431,10 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
return this.firSafeNullable()
|
||||
}
|
||||
|
||||
override fun nullableAnyType(): SimpleTypeMarker = TODO("not implemented")
|
||||
|
||||
override fun arrayType(componentType: KotlinTypeMarker): SimpleTypeMarker = TODO("not implemented")
|
||||
|
||||
override fun TypeConstructorMarker.isFinalClassOrEnumEntryOrAnnotationClassConstructor(): Boolean {
|
||||
val firRegularClass = toFirRegularClass() ?: return false
|
||||
|
||||
@@ -485,6 +489,8 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
|
||||
override fun TypeParameterMarker.getName() = (this as ConeTypeParameterSymbol).name
|
||||
|
||||
override fun TypeParameterMarker.isReified(): Boolean = TODO("not implemented")
|
||||
|
||||
override fun KotlinTypeMarker.isInterfaceOrAnnotationClass(): Boolean {
|
||||
val classKind = typeConstructor().toFirRegularClass()?.classKind ?: return false
|
||||
return classKind == ClassKind.ANNOTATION_CLASS || classKind == ClassKind.INTERFACE
|
||||
|
||||
+27
-16
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
@@ -908,12 +909,7 @@ class ExpressionCodegen(
|
||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(classType, ReifiedTypeInliner.OperationKind.JAVA_CLASS, mv, this)
|
||||
}
|
||||
|
||||
val asmType = typeMapper.mapType(classType)
|
||||
if (classType.getClass()?.isInline == true || !isPrimitive(asmType)) {
|
||||
mv.aconst(typeMapper.boxType(classType))
|
||||
} else {
|
||||
mv.getstatic(boxType(asmType).internalName, "TYPE", "Ljava/lang/Class;")
|
||||
}
|
||||
generateClassInstance(mv, classType)
|
||||
} else {
|
||||
throw AssertionError("not an IrGetClass or IrClassReference: ${classReference.dump()}")
|
||||
}
|
||||
@@ -924,6 +920,15 @@ class ExpressionCodegen(
|
||||
return classReference.onStack
|
||||
}
|
||||
|
||||
private fun generateClassInstance(v: InstructionAdapter, classType: IrType) {
|
||||
val asmType = typeMapper.mapType(classType)
|
||||
if (classType.getClass()?.isInline == true || !isPrimitive(asmType)) {
|
||||
v.aconst(typeMapper.boxType(classType))
|
||||
} else {
|
||||
v.getstatic(boxType(asmType).internalName, "TYPE", "Ljava/lang/Class;")
|
||||
}
|
||||
}
|
||||
|
||||
private fun getOrCreateCallGenerator(
|
||||
element: IrFunctionAccessExpression, data: BlockInfo, signature: JvmMethodSignature
|
||||
): IrCallGenerator {
|
||||
@@ -964,7 +969,19 @@ class ExpressionCodegen(
|
||||
val original = (callee as? IrSimpleFunction)?.resolveFakeOverride() ?: irFunction
|
||||
val methodOwner = callee.parent.safeAs<IrClass>()?.let(typeMapper::mapClass) ?: MethodSignatureMapper.FAKE_OWNER_TYPE
|
||||
val sourceCompiler = IrSourceCompilerForInline(state, element, this, data)
|
||||
return IrInlineCodegen(this, state, original.descriptor, methodOwner, signature, mappings, sourceCompiler)
|
||||
val typeParameterMappings = mappings.toTypeParameterMappings()
|
||||
|
||||
val reifiedTypeInliner = ReifiedTypeInliner(typeParameterMappings, object : ReifiedTypeInliner.IntrinsicsSupport<IrType> {
|
||||
override fun putClassInstance(v: InstructionAdapter, type: IrType) {
|
||||
generateClassInstance(v, type)
|
||||
}
|
||||
|
||||
override fun toKotlinType(type: IrType): KotlinType = type.toKotlinType()
|
||||
}, IrTypeCheckerContext(context.irBuiltIns), state.languageVersionSettings)
|
||||
|
||||
return IrInlineCodegen(
|
||||
this, state, original.descriptor, methodOwner, signature, typeParameterMappings, sourceCompiler, reifiedTypeInliner
|
||||
)
|
||||
}
|
||||
|
||||
private fun consumeReifiedOperationMarker(typeParameter: IrTypeParameter) {
|
||||
@@ -1099,23 +1116,17 @@ class IrTypeParameterMappings {
|
||||
mappingsByName.values.forEach(l)
|
||||
}
|
||||
|
||||
fun toTypeParameterMappings() = TypeParameterMappings().also { result ->
|
||||
fun toTypeParameterMappings() = TypeParameterMappings<IrType>().also { result ->
|
||||
mappingsByName.forEach { (_, value) ->
|
||||
if (value.asmType == null) {
|
||||
result.addParameterMappingForFurtherReification(
|
||||
value.name,
|
||||
value.type.toKotlinType(),
|
||||
value.type,
|
||||
value.reificationArgument!!.toReificationArgument(),
|
||||
value.isReified
|
||||
)
|
||||
} else {
|
||||
result.addParameterMappingToType(
|
||||
value.name,
|
||||
value.type.toKotlinType(),
|
||||
value.asmType,
|
||||
value.signature!!,
|
||||
value.isReified
|
||||
)
|
||||
result.addParameterMappingToType(value.name, value.type, value.asmType, value.signature!!, value.isReified)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -33,10 +33,11 @@ class IrInlineCodegen(
|
||||
function: FunctionDescriptor,
|
||||
methodOwner: Type,
|
||||
signature: JvmMethodSignature,
|
||||
typeParameterMappings: IrTypeParameterMappings,
|
||||
sourceCompiler: SourceCompilerForInline
|
||||
typeParameterMappings: TypeParameterMappings<IrType>,
|
||||
sourceCompiler: SourceCompilerForInline,
|
||||
reifiedTypeInliner: ReifiedTypeInliner<IrType>
|
||||
) : InlineCodegen<ExpressionCodegen>(
|
||||
codegen, state, function, methodOwner, signature, typeParameterMappings.toTypeParameterMappings(), sourceCompiler
|
||||
codegen, state, function, methodOwner, signature, typeParameterMappings, sourceCompiler, reifiedTypeInliner
|
||||
), IrCallGenerator {
|
||||
override fun generateAssertFieldIfNeeded(info: RootInliningContext) {
|
||||
// TODO: JVM assertions are not implemented yet in IR backend
|
||||
@@ -141,7 +142,7 @@ class IrExpressionLambdaImpl(
|
||||
val reference: IrFunctionReference,
|
||||
val function: IrFunction,
|
||||
private val typeMapper: IrTypeMapper,
|
||||
private val methodSignatureMapper: MethodSignatureMapper,
|
||||
methodSignatureMapper: MethodSignatureMapper,
|
||||
isCrossInline: Boolean,
|
||||
override val isBoundCallableReference: Boolean,
|
||||
override val isExtensionLambda: Boolean
|
||||
|
||||
@@ -267,6 +267,12 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
||||
override fun createErrorTypeWithCustomConstructor(debugName: String, constructor: TypeConstructorMarker): KotlinTypeMarker =
|
||||
TODO("IrTypeSystemContext doesn't support constraint system resolution")
|
||||
|
||||
override fun nullableAnyType(): SimpleTypeMarker =
|
||||
irBuiltIns.anyNType as IrSimpleType
|
||||
|
||||
override fun arrayType(componentType: KotlinTypeMarker): SimpleTypeMarker =
|
||||
irBuiltIns.arrayClass.typeWith(componentType as IrType)
|
||||
|
||||
override fun TypeConstructorMarker.isFinalClassOrEnumEntryOrAnnotationClassConstructor(): Boolean {
|
||||
val symbol = this as IrClassifierSymbol
|
||||
return symbol is IrClassSymbol && symbol.owner.let {
|
||||
@@ -340,6 +346,9 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
||||
override fun TypeParameterMarker.getName(): Name =
|
||||
(this as IrTypeParameterSymbol).owner.name
|
||||
|
||||
override fun TypeParameterMarker.isReified(): Boolean =
|
||||
(this as IrTypeParameterSymbol).owner.isReified
|
||||
|
||||
override fun KotlinTypeMarker.isInterfaceOrAnnotationClass(): Boolean {
|
||||
val irClass = (this as IrType).classOrNull?.owner
|
||||
return irClass != null && (irClass.isInterface || irClass.isAnnotationClass)
|
||||
|
||||
@@ -12,6 +12,9 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
|
||||
interface TypeSystemCommonBackendContext : TypeSystemContext {
|
||||
fun nullableAnyType(): SimpleTypeMarker
|
||||
fun arrayType(componentType: KotlinTypeMarker): SimpleTypeMarker
|
||||
|
||||
fun TypeConstructorMarker.isFinalClassOrEnumEntryOrAnnotationClassConstructor(): Boolean
|
||||
|
||||
fun KotlinTypeMarker.hasAnnotation(fqName: FqName): Boolean
|
||||
@@ -44,6 +47,7 @@ interface TypeSystemCommonBackendContext : TypeSystemContext {
|
||||
fun TypeConstructorMarker.getClassFqNameUnsafe(): FqNameUnsafe?
|
||||
|
||||
fun TypeParameterMarker.getName(): Name
|
||||
fun TypeParameterMarker.isReified(): Boolean
|
||||
|
||||
fun KotlinTypeMarker.isInterfaceOrAnnotationClass(): Boolean
|
||||
}
|
||||
|
||||
+12
-1
@@ -341,7 +341,8 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
||||
return builtIns.anyType
|
||||
}
|
||||
|
||||
val builtIns: KotlinBuiltIns get() = throw UnsupportedOperationException("Not supported")
|
||||
open val builtIns: KotlinBuiltIns
|
||||
get() = throw UnsupportedOperationException("Not supported")
|
||||
|
||||
override fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker {
|
||||
require(this is UnwrappedType, this::errorMessage)
|
||||
@@ -502,6 +503,11 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
||||
return this is NewCapturedTypeConstructor
|
||||
}
|
||||
|
||||
override fun arrayType(componentType: KotlinTypeMarker): SimpleTypeMarker {
|
||||
require(componentType is KotlinType, this::errorMessage)
|
||||
return builtIns.getArrayType(Variance.INVARIANT, componentType)
|
||||
}
|
||||
|
||||
override fun KotlinTypeMarker.hasAnnotation(fqName: FqName): Boolean {
|
||||
require(this is KotlinType, this::errorMessage)
|
||||
return annotations.hasAnnotation(fqName)
|
||||
@@ -557,6 +563,11 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
||||
return name
|
||||
}
|
||||
|
||||
override fun TypeParameterMarker.isReified(): Boolean {
|
||||
require(this is TypeParameterDescriptor, this::errorMessage)
|
||||
return isReified
|
||||
}
|
||||
|
||||
override fun KotlinTypeMarker.isInterfaceOrAnnotationClass(): Boolean {
|
||||
require(this is KotlinType, this::errorMessage)
|
||||
val descriptor = constructor.declarationDescriptor
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.types.checker
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
@@ -31,6 +32,8 @@ import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
|
||||
object SimpleClassicTypeSystemContext : ClassicTypeSystemContext
|
||||
|
||||
class ClassicTypeSystemContextImpl(override val builtIns: KotlinBuiltIns) : ClassicTypeSystemContext
|
||||
|
||||
object StrictEqualityTypeChecker {
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user