K2: add test plugin visitor checking source elements presence

Related to KT-60555, KT-61330
This commit is contained in:
Mikhail Glukhikh
2023-08-29 11:18:24 +02:00
committed by Space Team
parent 4d9457862f
commit c695d2759a
8 changed files with 204 additions and 0 deletions
@@ -17,6 +17,7 @@ dependencies {
compileOnly(project(":compiler:fir:entrypoint"))
compileOnly(project(":compiler:plugin-api"))
compileOnly(intellijCore())
compileOnly(commonDependency("org.jetbrains.intellij.deps:asm-all"))
testApiJUnit5()
testApi(projectTests(":compiler:tests-common-new"))
@@ -21,6 +21,7 @@ class GeneratedDeclarationsIrBodyFiller : IrGenerationExtension {
TransformerForAddingAnnotations(pluginContext),
ComposableFunctionsTransformer(pluginContext),
BodyWithDefaultValueReplacer(),
SourceElementChecker(pluginContext),
)
for (transformer in transformers) {
@@ -0,0 +1,70 @@
/*
* Copyright 2010-2023 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.plugin
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.java.JavaBinarySourceElement
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.load.java.structure.impl.VirtualFileBoundJavaClass
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
@OptIn(IrSymbolInternals::class)
class SourceElementChecker(val context: IrPluginContext) : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
override fun visitFunction(declaration: IrFunction) {
val type = declaration.returnType as? IrSimpleType ?: return
val klass = type.classifier.owner as? IrClass ?: return
if (klass.startOffset != UNDEFINED_OFFSET) {
return
}
if (klass.origin is IrDeclarationOrigin.GeneratedByPlugin) {
return
}
if (klass is Fir2IrLazyClass && klass.fir.origin == FirDeclarationOrigin.BuiltIns) {
return
}
when (val sourceElement = klass.source) {
is KotlinJvmBinarySourceElement -> {
val binaryClass = sourceElement.binaryClass
if (binaryClass !is VirtualFileKotlinClass) {
throw AssertionError("No virtual file found: ${binaryClass.classId}")
}
}
is JavaBinarySourceElement -> {
val javaClass = sourceElement.javaClass
(javaClass as VirtualFileBoundJavaClass).virtualFile
?: throw AssertionError("No virtual file found: ${javaClass.fqName}")
}
is DeserializedContainerSource -> {
// Klib element is possible here in JS test
return
}
SourceElement.NO_SOURCE -> {
throw AssertionError("No source found: ${klass.fqNameForIrSerialization}")
}
else -> {
throw AssertionError("Unknown source element: ${sourceElement.javaClass}")
}
}
}
}
@@ -0,0 +1,60 @@
FILE: builtins.kt
public final fun foo1(): R|kotlin/Unit| {
}
public final fun foo2(): R|kotlin/Int| {
^foo2 Int(2)
}
public final fun foo3(): R|kotlin/Short| {
^foo3 Short(3)
}
public final fun foo4(): R|kotlin/Byte| {
^foo4 Byte(4)
}
public final fun foo5(): R|kotlin/Long| {
^foo5 Long(5)
}
public final fun foo6(): R|kotlin/Float| {
^foo6 Float(6.0)
}
public final fun foo7(): R|kotlin/Double| {
^foo7 Double(7.0)
}
public final fun foo8(): R|kotlin/Char| {
^foo8 Char(8)
}
public final fun foo9(): R|kotlin/Boolean| {
^foo9 Boolean(true)
}
public final fun foo10(): R|kotlin/String| {
^foo10 String(10)
}
public final fun foo11(): R|kotlin/collections/List<kotlin/String>| {
^foo11 R|kotlin/collections/listOf|<R|kotlin/String|>(String(11))
}
public final fun foo12(): R|kotlin/collections/MutableList<kotlin/String>| {
^foo12 R|kotlin/collections/mutableListOf|<R|kotlin/String|>(vararg(String(12)))
}
public final fun foo13(): R|kotlin/Any| {
^foo13 Int(13)
}
public final fun foo14(): R|kotlin/Nothing| {
^foo14 R|kotlin/TODO|()
}
public final fun foo15(): R|() -> kotlin/Int| {
^foo15 fun <anonymous>(): R|kotlin/Int| <inline=Unknown> {
^ Int(15)
}
}
public final fun foo16(): R|kotlin/Array<kotlin/String>| {
^foo16 R|kotlin/arrayOf|<R|kotlin/String|>(vararg(String(16)))
}
public final fun foo17(): R|kotlin/Number| {
^foo17 Int(17)
}
public final fun foo18(): R|kotlin/annotation/AnnotationTarget| {
^foo18 Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.CLASS|
}
public final fun box(): R|kotlin/String| {
^box String(OK)
}
+39
View File
@@ -0,0 +1,39 @@
// WITH_STDLIB
fun foo1() {}
fun foo2(): Int = 2
fun foo3(): Short = 3
fun foo4(): Byte = 4
fun foo5(): Long = 5L
fun foo6(): Float = 6.0f
fun foo7(): Double = 7.0
fun foo8(): Char = '8'
fun foo9(): Boolean = true
fun foo10(): String = "10"
fun foo11(): List<String> = listOf("11")
fun foo12(): MutableList<String> = mutableListOf("12")
fun foo13(): Any = 13
fun foo14(): Nothing = TODO()
fun foo15(): () -> Int = { 15 }
fun foo16(): Array<String> = arrayOf("16")
fun foo17(): Number = 17
fun foo18(): AnnotationTarget = AnnotationTarget.CLASS
fun box() = "OK"
@@ -0,0 +1,13 @@
FILE: extendsJava.kt
public final class A : R|java/io/File| {
public constructor(): R|A| {
super<R|java/io/File|>(String(A))
}
}
public final fun foo(): R|A| {
^foo R|kotlin/TODO|()
}
public final fun box(): R|kotlin/String| {
^box String(OK)
}
@@ -0,0 +1,8 @@
// FULL_JDK
import java.io.File;
class A : File("A")
fun foo(): A = TODO()
fun box() = "OK"
@@ -25,6 +25,12 @@ public class FirLightTreePluginBlackBoxCodegenTestGenerated extends AbstractFirL
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/fir-plugin-prototype/testData/box"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("builtins.kt")
public void testBuiltins() throws Exception {
runTest("plugins/fir-plugin-prototype/testData/box/builtins.kt");
}
@Test
@TestMetadata("classWithAllPropertiesConstructor.kt")
public void testClassWithAllPropertiesConstructor() throws Exception {
@@ -55,6 +61,12 @@ public class FirLightTreePluginBlackBoxCodegenTestGenerated extends AbstractFirL
runTest("plugins/fir-plugin-prototype/testData/box/expectComposableFunction.kt");
}
@Test
@TestMetadata("extendsJava.kt")
public void testExtendsJava() throws Exception {
runTest("plugins/fir-plugin-prototype/testData/box/extendsJava.kt");
}
@Test
@TestMetadata("generatedClassWithMembersAndNestedClasses.kt")
public void testGeneratedClassWithMembersAndNestedClasses() throws Exception {