From afe335e5041ed4739d5995bde58b149dd29694fc Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 19 Jan 2021 10:11:09 +0300 Subject: [PATCH] FIR: serialize ExtensionFunctionType attribute --- .../FirBlackBoxCodegenTestGenerated.java | 16 +++++++++ .../fir/serialization/FirElementSerializer.kt | 35 +++++++++++++++++-- .../serialization/FirSerializerExtension.kt | 4 +-- .../backend/jvm/FirJvmSerializerExtension.kt | 9 +++-- .../codegen/box/fir/ExtensionAlias.kt | 24 +++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 16 +++++++++ .../IrBlackBoxCodegenTestGenerated.java | 16 +++++++++ .../LightAnalysisModeTestGenerated.java | 18 ++++++++++ .../IrJsCodegenBoxES6TestGenerated.java | 13 +++++++ .../IrJsCodegenBoxTestGenerated.java | 13 +++++++ .../semantics/JsCodegenBoxTestGenerated.java | 13 +++++++ .../IrCodegenBoxWasmTestGenerated.java | 13 +++++++ 12 files changed, 180 insertions(+), 10 deletions(-) create mode 100644 compiler/testData/codegen/box/fir/ExtensionAlias.kt diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index e45be44ded4..70037cfadb9 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -13697,6 +13697,22 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT } } + @Nested + @TestMetadata("compiler/testData/codegen/box/fir") + @TestDataPath("$PROJECT_ROOT") + public class Fir extends AbstractFirBlackBoxCodegenTest { + @Test + public void testAllFilesPresentInFir() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @Test + @TestMetadata("ExtensionAlias.kt") + public void testExtensionAlias() throws Exception { + runTest("compiler/testData/codegen/box/fir/ExtensionAlias.kt"); + } + } + @Nested @TestMetadata("compiler/testData/codegen/box/fullJdk") @TestDataPath("$PROJECT_ROOT") 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 a39091afe37..c4ea60f4f85 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 @@ -21,6 +21,8 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirArgumentList import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression +import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationCall +import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.calls.varargElementType import org.jetbrains.kotlin.fir.resolve.firSymbolProvider @@ -35,6 +37,7 @@ import org.jetbrains.kotlin.fir.serialization.constant.toConstantValue import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.impl.FirImplicitNullableAnyTypeRef import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.deserialization.Flags @@ -548,12 +551,14 @@ class FirElementSerializer private constructor( fun typeId(type: ConeKotlinType): Int = typeTable[typeProto(type)] private fun typeProto(typeRef: FirTypeRef, toSuper: Boolean = false): ProtoBuf.Type.Builder { - return typeProto(typeRef.coneType, toSuper).also { - extension.serializeType(typeRef, it) + return typeProto(typeRef.coneType, toSuper, correspondingTypeRef = typeRef).also { + for (annotation in typeRef.annotations) { + extension.serializeTypeAnnotation(annotation, it) + } } } - private fun typeProto(type: ConeKotlinType, toSuper: Boolean = false): ProtoBuf.Type.Builder { + private fun typeProto(type: ConeKotlinType, toSuper: Boolean = false, correspondingTypeRef: FirTypeRef? = null): ProtoBuf.Type.Builder { val builder = ProtoBuf.Type.newBuilder() when (type) { @@ -580,6 +585,11 @@ class FirElementSerializer private constructor( return functionType } fillFromPossiblyInnerType(builder, type) + if (type.isExtensionFunctionType) { + serializeAnnotationFromAttribute( + correspondingTypeRef?.annotations, CompilerConeAttributes.ExtensionFunctionType.ANNOTATION_CLASS_ID, builder + ) + } } is ConeTypeParameterType -> { val typeParameter = type.lookupTag.typeParameterSymbol.fir @@ -629,6 +639,25 @@ class FirElementSerializer private constructor( return builder } + private fun serializeAnnotationFromAttribute( + existingAnnotations: List?, + classId: ClassId, + builder: ProtoBuf.Type.Builder + ) { + if (existingAnnotations?.any { it.annotationTypeRef.coneTypeSafe()?.classId == classId } != true) { + extension.serializeTypeAnnotation( + buildAnnotationCall { + calleeReference = FirReferencePlaceholderForResolvedAnnotations + annotationTypeRef = buildResolvedTypeRef { + this.type = CompilerConeAttributes.ExtensionFunctionType.ANNOTATION_CLASS_ID.constructClassLikeType( + emptyArray(), isNullable = false + ) + } + }, builder + ) + } + } + private fun transformSuspendFunctionToRuntimeFunctionType(type: ConeClassLikeType): ConeClassLikeType { val suspendClassId = type.classId!! val relativeClassName = suspendClassId.relativeClassName.asString() diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirSerializerExtension.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirSerializerExtension.kt index cf49979611c..c7e0847fe98 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirSerializerExtension.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirSerializerExtension.kt @@ -7,9 +7,9 @@ package org.jetbrains.kotlin.fir.serialization import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.types.ConeFlexibleType import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType -import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable @@ -74,7 +74,7 @@ abstract class FirSerializerExtension { open fun serializeFlexibleType(type: ConeFlexibleType, lowerProto: ProtoBuf.Type.Builder, upperProto: ProtoBuf.Type.Builder) { } - open fun serializeType(type: FirTypeRef, proto: ProtoBuf.Type.Builder) { + open fun serializeTypeAnnotation(annotation: FirAnnotationCall, proto: ProtoBuf.Type.Builder) { } open fun serializeTypeParameter(typeParameter: FirTypeParameter, proto: ProtoBuf.TypeParameter.Builder) { diff --git a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt index 80d41bf2e3d..57f53a79d03 100644 --- a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt +++ b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.backend.Fir2IrComponents import org.jetbrains.kotlin.fir.backend.FirMetadataSource import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.resolve.firProvider import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType import org.jetbrains.kotlin.fir.serialization.FirElementSerializer @@ -173,13 +174,11 @@ class FirJvmSerializerExtension( } } - override fun serializeType(type: FirTypeRef, proto: ProtoBuf.Type.Builder) { - // TODO: don't store type annotations in our binary metadata on Java 8, use *TypeAnnotations attributes instead - for (annotation in type.annotations) { - proto.addExtension(JvmProtoBuf.typeAnnotation, annotationSerializer.serializeAnnotation(annotation)) - } + override fun serializeTypeAnnotation(annotation: FirAnnotationCall, proto: ProtoBuf.Type.Builder) { + proto.addExtension(JvmProtoBuf.typeAnnotation, annotationSerializer.serializeAnnotation(annotation)) } + override fun serializeTypeParameter(typeParameter: FirTypeParameter, proto: ProtoBuf.TypeParameter.Builder) { for (annotation in typeParameter.nonSourceAnnotations(session)) { proto.addExtension(JvmProtoBuf.typeParameterAnnotation, annotationSerializer.serializeAnnotation(annotation)) diff --git a/compiler/testData/codegen/box/fir/ExtensionAlias.kt b/compiler/testData/codegen/box/fir/ExtensionAlias.kt new file mode 100644 index 00000000000..befe45402d5 --- /dev/null +++ b/compiler/testData/codegen/box/fir/ExtensionAlias.kt @@ -0,0 +1,24 @@ +// TARGET_BACKEND: JVM +// MODULE: lib +// FILE: A.kt + +typealias ProcessOverriddenWithBaseScope = String.(D, (D, String) -> Boolean) -> Boolean + +// MODULE: main(lib) +// FILE: B.kt + +private data class NumberWithString(val n: N, val s: String) + +private fun use(ns: NumberWithString, process: ProcessOverriddenWithBaseScope): String { + val (n, s) = ns + val result = s.process(n) { _, s -> + s == "OK" + } + return if (result) "OK" else "FAIL" +} + +fun box(): String { + return use(NumberWithString(42, "OK")) { n, process -> + process(n, "OK") + } +} \ No newline at end of file diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index de0bf7c0340..7dac22b9a70 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -13697,6 +13697,22 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } } + @Nested + @TestMetadata("compiler/testData/codegen/box/fir") + @TestDataPath("$PROJECT_ROOT") + public class Fir extends AbstractBlackBoxCodegenTest { + @Test + public void testAllFilesPresentInFir() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @Test + @TestMetadata("ExtensionAlias.kt") + public void testExtensionAlias() throws Exception { + runTest("compiler/testData/codegen/box/fir/ExtensionAlias.kt"); + } + } + @Nested @TestMetadata("compiler/testData/codegen/box/fullJdk") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 1d4fcac0785..07e9c9bff98 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -13697,6 +13697,22 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes } } + @Nested + @TestMetadata("compiler/testData/codegen/box/fir") + @TestDataPath("$PROJECT_ROOT") + public class Fir extends AbstractIrBlackBoxCodegenTest { + @Test + public void testAllFilesPresentInFir() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @Test + @TestMetadata("ExtensionAlias.kt") + public void testExtensionAlias() throws Exception { + runTest("compiler/testData/codegen/box/fir/ExtensionAlias.kt"); + } + } + @Nested @TestMetadata("compiler/testData/codegen/box/fullJdk") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 8d42b316610..b5edeb1f535 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -12030,6 +12030,24 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes } } + @TestMetadata("compiler/testData/codegen/box/fir") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Fir extends AbstractLightAnalysisModeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInFir() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @TestMetadata("ExtensionAlias.kt") + public void testExtensionAlias() throws Exception { + runTest("compiler/testData/codegen/box/fir/ExtensionAlias.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/fullJdk") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 0ffa287b7ea..e46e1454e62 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -10295,6 +10295,19 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes } } + @TestMetadata("compiler/testData/codegen/box/fir") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Fir extends AbstractIrJsCodegenBoxES6Test { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath); + } + + public void testAllFilesPresentInFir() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); + } + } + @TestMetadata("compiler/testData/codegen/box/fullJdk") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 24990b3bda6..79d643230e5 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -10295,6 +10295,19 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { } } + @TestMetadata("compiler/testData/codegen/box/fir") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Fir extends AbstractIrJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + public void testAllFilesPresentInFir() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } + } + @TestMetadata("compiler/testData/codegen/box/fullJdk") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index b0b919405af..30ef2e712cc 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -10295,6 +10295,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { } } + @TestMetadata("compiler/testData/codegen/box/fir") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Fir extends AbstractJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + public void testAllFilesPresentInFir() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); + } + } + @TestMetadata("compiler/testData/codegen/box/fullJdk") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index ad33bfcffb5..32c76383dda 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -5171,6 +5171,19 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest } } + @TestMetadata("compiler/testData/codegen/box/fir") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Fir extends AbstractIrCodegenBoxWasmTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath); + } + + public void testAllFilesPresentInFir() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true); + } + } + @TestMetadata("compiler/testData/codegen/box/fullJdk") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)