From 3a8f1ca69055355a0d142521908b16c2f19b8ce9 Mon Sep 17 00:00:00 2001 From: Mads Ager Date: Thu, 16 Mar 2023 12:49:36 +0100 Subject: [PATCH] [K2] Type parameter metadata handling. --- .../fir/serialization/FirElementSerializer.kt | 67 ++++++++++++------- .../kotlin/kotlinp/test/KotlinpTestUtils.kt | 1 - .../tools/kotlinp/testData/TypeParameters.kt | 4 +- .../tools/kotlinp/testData/TypeParameters.txt | 3 + 4 files changed, 48 insertions(+), 27 deletions(-) diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt index f0a5b3630b9..2d3f00fb197 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt @@ -27,8 +27,10 @@ import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyAnnotationArgumentMapping import org.jetbrains.kotlin.fir.extensions.extensionService import org.jetbrains.kotlin.fir.extensions.typeAttributeExtensions -import org.jetbrains.kotlin.fir.resolve.* +import org.jetbrains.kotlin.fir.resolve.ScopeSession +import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider +import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.scopes.* import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope import org.jetbrains.kotlin.fir.serialization.constant.* @@ -884,35 +886,52 @@ class FirElementSerializer private constructor( } } } - + + private fun fillFromPossiblyInnerType( + builder: ProtoBuf.Type.Builder, + symbol: FirClassLikeSymbol<*>, + typeArguments: Array, + typeArgumentIndex: Int + ) { + var argumentIndex = typeArgumentIndex + val classifier = symbol.fir + val classifierId = getClassifierId(classifier) + if (classifier is FirTypeAlias) { + builder.typeAliasName = classifierId + } else { + builder.className = classifierId + } + for (i in 0 until classifier.typeParameters.size) { + // Next type parameter is not for this type but for an outer type. + if (classifier.typeParameters[i] !is FirTypeParameter) break + // No explicit type argument provided. For example: `Map.Entry` when we get to `Map` + // it has type parameters, but no explicit type arguments are provided for it. + if (argumentIndex >= typeArguments.size) return + builder.addArgument(typeArgument(typeArguments[argumentIndex++])) + } + + val outerClassId = symbol.classId.outerClassId + if (outerClassId == null || outerClassId.isLocal) return + val outerSymbol = outerClassId.toLookupTag().toSymbol(session) + if (outerSymbol != null) { + val outerBuilder = ProtoBuf.Type.newBuilder() + fillFromPossiblyInnerType(outerBuilder, outerSymbol, typeArguments, argumentIndex) + if (useTypeTable()) { + builder.outerTypeId = typeTable[outerBuilder] + } else { + builder.setOuterType(outerBuilder) + } + } + } + private fun fillFromPossiblyInnerType(builder: ProtoBuf.Type.Builder, type: ConeClassLikeType) { val classifierSymbol = type.lookupTag.toSymbol(session) if (classifierSymbol != null) { - val classifier = classifierSymbol.fir - val classifierId = getClassifierId(classifier) - if (classifier is FirTypeAlias) { - builder.typeAliasName = classifierId - } else { - builder.className = classifierId - } + fillFromPossiblyInnerType(builder, classifierSymbol, type.typeArguments, 0) } else { builder.className = getClassifierId(type.lookupTag.classId) + type.typeArguments.forEach { builder.addArgument(typeArgument(it)) } } - - for (projection in type.typeArguments) { - builder.addArgument(typeArgument(projection)) - } - - // TODO: outer type -// if (type.outerType != null) { -// val outerBuilder = ProtoBuf.Type.newBuilder() -// fillFromPossiblyInnerType(outerBuilder, type.outerType!!) -// if (useTypeTable()) { -// builder.outerTypeId = typeTable[outerBuilder] -// } else { -// builder.setOuterType(outerBuilder) -// } -// } } private fun typeArgument(typeProjection: ConeTypeProjection): ProtoBuf.Type.Argument.Builder { diff --git a/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/KotlinpTestUtils.kt b/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/KotlinpTestUtils.kt index ec438f87c50..a524772e10b 100644 --- a/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/KotlinpTestUtils.kt +++ b/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/KotlinpTestUtils.kt @@ -18,7 +18,6 @@ import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.jvm.compiler.AbstractLoadJavaTest import org.jetbrains.kotlin.kotlinp.Kotlinp import org.jetbrains.kotlin.kotlinp.KotlinpSettings -import org.jetbrains.kotlin.load.java.JavaTypeEnhancementState import org.jetbrains.kotlin.test.ConfigurationKind import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.jetbrains.kotlin.test.KotlinTestUtils diff --git a/libraries/tools/kotlinp/testData/TypeParameters.kt b/libraries/tools/kotlinp/testData/TypeParameters.kt index d23095c7725..97d8885a9d4 100644 --- a/libraries/tools/kotlinp/testData/TypeParameters.kt +++ b/libraries/tools/kotlinp/testData/TypeParameters.kt @@ -1,8 +1,8 @@ -// IGNORE K2 - class A { fun a(t: T) {} + fun f(m: Map.Entry) {} + inner class B { fun b(t: T, u: U & Any, v: V) where T : Comparable, T : Cloneable {} diff --git a/libraries/tools/kotlinp/testData/TypeParameters.txt b/libraries/tools/kotlinp/testData/TypeParameters.txt index 94f88efbdc9..04f8298e7c0 100644 --- a/libraries/tools/kotlinp/testData/TypeParameters.txt +++ b/libraries/tools/kotlinp/testData/TypeParameters.txt @@ -8,6 +8,9 @@ public final class A : kotlin/Any { // signature: a(Ljava/lang/Object;)V public final fun a(t: T#1): kotlin/Unit + // signature: f(Ljava/util/Map$Entry;)V + public final fun f(m: kotlin/collections/Map.Entry): kotlin/Unit + // nested class: B // module name: test-module