[Wasm] Add K2 diagnostic tests (KT-56849)

This commit is contained in:
Svyatoslav Kuzmich
2023-09-11 12:01:48 +02:00
committed by Space Team
parent 1ddcdb95bd
commit 0da9cf8159
13 changed files with 626 additions and 4 deletions
@@ -0,0 +1,8 @@
val foo: dynamic = 1
fun foo(x: dynamic): dynamic {
class C {
val foo: dynamic = 1
}
return x + C().foo
}
@@ -0,0 +1,51 @@
// Classes
external class C1
external enum class C2
external annotation class C3
external data class C4(val x: String)
external class C5 {
class C6
inner class C7
}
external inline class C8(val x: Int)
external value class C9(val x: Int)
// Interfaces
external interface I1
external fun interface I2 {
fun foo(): Int
}
// Functions
external fun foo1(): Int
external <!NO_TAIL_CALLS_FOUND!>tailrec<!> fun foo2(): Int
external inline fun foo3(f: () -> Int): Int
external suspend fun foo4(): Int
external fun Int.foo5(): Int
// Properties
external lateinit var v1: String
external val Int.v2: String
get() = definedExternally
@@ -0,0 +1,22 @@
open class C1
interface I1
external open class EC1
external class EC2 : C1
external class EC3 : I1, C1
external interface EI1 : I1
interface I2 : EI1
class C3 : EI1
class C4 : EI1, EC1()
object O1 : EC1()
val x1: Any = object : EI1 {}
val x2: Any = object : EC1() {}
@@ -0,0 +1,113 @@
val prop: Int =
js("1")
fun funExprBody(x: Int): Int =
js("x")
fun funBlockBody(x: Int): Int {
js("return x;")
}
fun <!IMPLICIT_NOTHING_RETURN_TYPE!>returnTypeNotSepcified<!>() = js("1")
val <!IMPLICIT_NOTHING_PROPERTY_TYPE!>valTypeNotSepcified<!> = js("1")
val a = "1"
fun nonConst(): String = "1"
val p0: Int = js(a)
val p1: Int = js(("1"))
val p2: Int = js("$a")
val p3: Int = js("${1}")
val p4: Int = js("${a}${a}")
val p5: Int = js(a + a)
val p6: Int = js("1" + "1")
val p7: Int = js(nonConst())
val propWithGetter: String
get() = "1"
val propWithSimpleGetterAndInitializer: String = "1"
get() = field + "2"
val propWithComplexGetterAndInitializer: String = "1"
get() = run { field + "2" }
var varProp = "1"
var varPropWithSetter = "1"
set(value) { field = field + value }
const val constProp = "1"
val delegatedVal: String by lazy { "1" }
val p8: Int = js(propWithGetter)
// TODO: This should be an error as property getters are no different to functions
val p9: Int = js(propWithSimpleGetterAndInitializer)
val p10: Int = js(propWithComplexGetterAndInitializer)
val p11: Int = js(varProp)
val p12: Int = js(varPropWithSetter)
val p13: Int = js(constProp)
val p14: Int = js(delegatedVal)
fun foo0(b: Boolean): Int =
if (b) js("1") else js("2")
fun foo1(): Int {
println()
js("return x;")
}
fun foo11() {
fun local1(): Int = js("1")
fun local2(): Int {
js("return 1;")
}
fun local3(): Int {
println()
js("return 1;")
}
}
class C {
fun memberFun1(): Int = js("1")
fun memberFun2(): Int {
js("return 1;")
}
constructor() {
js("1;")
}
init {
js("1")
}
val memberProperty: Int = js("1")
}
fun withDefault(x: Int = js("1")) {
println(x)
}
suspend fun suspendFun(): Int = js("1")
inline fun inlineFun(f: () -> Int): Int = js("f()")
fun Int.extensionFun(): Int = js("1")
var propertyWithAccessors: Int
get(): Int = js("1")
set(value: Int) {
js("console.log(value);")
}
fun invalidNames(
`a b`: Int,
`1b`: Int,
`ab$`: Int
): Int = js("1")
@@ -0,0 +1,25 @@
// !OPT_IN: kotlin.js.ExperimentalJsExport
@JsExport
fun foo1() {
}
class C {
@JsExport
fun memberFunction() {
}
}
fun foo2() {
@JsExport
fun localFun() {
}
}
val p1 = (@JsExport fun () {})
<!WRONG_ANNOTATION_TARGET!>@JsExport<!>
class C2
<!WRONG_ANNOTATION_TARGET!>@JsExport<!>
var p2: Int = 1
@@ -0,0 +1,15 @@
@JsFun("() => {}")
external fun topLevelExternalFun(): Unit
external class ExternalClass {
@JsFun("() => {}")
fun memberFun(): Unit
}
@JsFun("() => {}")
fun topLevelNonExternalFun(): Unit {}
class NonExternalClass {
@JsFun("() => {}")
fun memberFun(): Unit {}
}
@@ -0,0 +1,111 @@
// !OPT_IN: kotlin.js.ExperimentalJsExport
external interface EI
external open class EC
external object EO
external fun supportedTypes(
boolean: Boolean,
byte: Byte,
short: Short,
int: Int,
long: Long,
float: Float,
double: Double,
char: Char,
string: String,
ei: EI,
ec: EC,
eo: EO,
f1: (Boolean, Byte, Short, Int, Long, Float, Double, Char, String, EI, EC, EO) -> Unit,
f2: (Boolean) -> ((Int) -> ((Float) -> ((String) -> EI))),
f3: ((((Boolean) -> Int) -> Float) -> String) -> EI,
): Unit
external fun supportedNullableTypes(
boolean: Boolean?,
byte: Byte?,
short: Short?,
int: Int?,
long: Long?,
float: Float?,
double: Double?,
char: Char?,
string: String?,
ei: EI?,
ec: EC?,
eo: EO?,
f1: ((Boolean?, Byte?, Short?, Int?, Long?, Float?, Double?, Char?, String?, EI?, EC?, EO?) -> Unit)?,
f2: ((Boolean?) -> ((Int?) -> ((Float?) -> ((String?) -> EI)?)?)?)?,
f3: ((((((((Boolean?) -> Int?)?) -> Float?)?) -> String?)?) -> EI?)?,
): Unit
external fun supportedReturnTypeUnit(): Unit
external fun supportedReturnTypeNothing(): Nothing
external fun supportedReturnTypeBoolean(): Boolean
external fun supportedReturnTypeNullableInt(): Int?
external fun supportedReturnTypeEI(): EI
external fun supportedReturnTypeNullableEC(): EC?
external fun <
T1 : EI,
T2 : EC?,
T3 : T1?
> supportedTypeParamtersUpperBounds(p1: T1, p2: T2): T3
external fun wrongExternalTypes(
any: Any,
nany: Any?,
unit: Unit,
nunit: Unit?,
nothing: Nothing,
nnothing: Nothing?,
charSequence: CharSequence,
list: List<Int>,
array: Array<Int>,
intArray: IntArray,
pair: Pair<Int, Int>,
number: Number,
)
external fun <T> supportedTypeParamtersUpperBounds(p: T): T where T : EI, T : Any
external fun <
T1,
T2 : Number,
T3: List<Int>,
> supportedTypeParamtersUpperBounds(
p1: T1,
p2: T2
): T3
fun jsCode1(x: Any): Any = js("x")
fun jsCode2(x: Any): Any {
js("return x;")
}
val jsProp: Any = js("1")
@JsExport
fun exported(x: Any): Any = x
typealias EI_alias = EI
typealias Any_alias = Any
external fun fooAlias(
ei: EI_alias,
any: Any_alias,
)
@@ -0,0 +1,58 @@
import kotlin.wasm.WasmExport
@WasmExport("a")
external fun foo0(): Unit
@WasmExport("a")
fun foo1(): Int = js("42")
class C() {
@WasmExport("a")
fun foo2(): Int = 42
}
@WasmExport("a")
fun foo3(): Int = 42
@WasmExport()
fun foo4(): Int = 42
@OptIn(kotlin.js.ExperimentalJsExport::class)
@JsExport()
@WasmExport()
fun foo6(): Int = 42
val p1 = (@WasmExport("a") fun () {})
@WasmExport("a")
fun foo7(
p0: Unit,
p1: String,
p2: Any,
p3: Int?,
p4: Boolean?
): Unit {
p0.toString()
p1.toString()
p2.toString()
p3.toString()
p4.toString()
}
@WasmExport("a")
fun returnNullableUnit(): Unit? { return null }
@WasmExport("a")
fun returnNullableBoolean(): Boolean? { return null }
@WasmExport("a")
fun returnNullableAny(): Any? { return null }
@WasmExport("a")
fun <T> fooGeneric(x: T): T { return x }
@WasmExport("a")
fun fooDeafultAndVararg(
a: Int = definedExternally,
vararg b: Int
): Unit { b.toString() }
@@ -0,0 +1,49 @@
import kotlin.wasm.WasmImport
@WasmImport("a", "b")
external fun foo0(): Unit
@WasmImport("a", "b")
fun foo1() {
}
external class C {
@WasmImport("a", "b")
fun memberFunction()
}
fun foo2() {
@WasmImport("a", "b")
fun localFun() {
}
}
val p1 = (@WasmImport("a", "b") fun () {})
@WasmImport("a", "b")
external fun foo3(
p0: Unit,
p1: String,
p2: Any,
p3: Int?,
p4: Boolean?
): Unit
@WasmImport("a", "b")
external fun returnNullableUnit(): Unit?
@WasmImport("a", "b")
external fun returnNullableBoolean(): Boolean?
@WasmImport("a", "b")
external fun returnNullableAny(): Any?
@WasmImport("a", "b")
external fun <T> fooGeneric(x: T): T
@WasmImport("a", "b")
external fun fooDeafultAndVararg(
a: Int = definedExternally,
vararg b: Int
): Unit
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.generators.tests
import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5
import org.jetbrains.kotlin.wasm.test.*
import org.jetbrains.kotlin.wasm.test.diagnostics.AbstractDiagnosticsWasmTest
import org.jetbrains.kotlin.wasm.test.diagnostics.AbstractDiagnosticsFirWasmTest
fun main(args: Array<String>) {
System.setProperty("java.awt.headless", "true")
@@ -24,11 +25,16 @@ fun main(args: Array<String>) {
// Multimodal infra is not supported. Also, we don't use ES modules for cross-module refs in Wasm
"crossModuleRef", "crossModuleRefPerFile", "crossModuleRefPerModule"
)
val excludedFirTestdataPattern = "^(.+)\\.fir\\.kts?\$"
generateTestGroupSuiteWithJUnit5(args) {
testGroup("wasm/wasm.tests/tests-gen", "compiler/testData") {
testClass<AbstractDiagnosticsWasmTest> {
model("diagnostics/wasmTests")
model("diagnostics/wasmTests", excludedPattern = excludedFirTestdataPattern)
}
testClass<AbstractDiagnosticsFirWasmTest> {
model("diagnostics/wasmTests", excludedPattern = excludedFirTestdataPattern)
}
}
@@ -0,0 +1,64 @@
/*
* 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.wasm.test.diagnostics
import org.jetbrains.kotlin.platform.wasm.WasmPlatforms
import org.jetbrains.kotlin.test.FirParser
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.firHandlersStep
import org.jetbrains.kotlin.test.directives.configureFirParser
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade
import org.jetbrains.kotlin.test.frontend.fir.handlers.*
import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest
import org.jetbrains.kotlin.test.runners.configurationForClassicAndFirTestsAlongside
import org.jetbrains.kotlin.test.services.LibraryProvider
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.configuration.WasmEnvironmentConfiguratorJs
import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
abstract class AbstractFirWasmDiagnosticTestBase(val parser: FirParser) : AbstractKotlinCompilerTest() {
override fun TestConfigurationBuilder.configuration() {
globalDefaults {
frontend = FrontendKinds.FIR
targetPlatform = WasmPlatforms.Default
dependencyKind = DependencyKind.Source
}
configureFirParser(parser)
enableMetaInfoHandler()
configurationForClassicAndFirTestsAlongside()
useConfigurators(
::CommonEnvironmentConfigurator,
::WasmEnvironmentConfiguratorJs,
)
useAdditionalSourceProviders(
::AdditionalDiagnosticsSourceFilesProvider,
::CoroutineHelpersSourceFilesProvider,
)
useAdditionalService(::LibraryProvider)
facadeStep(::FirFrontendFacade)
firHandlersStep {
useHandlers(
::FirDiagnosticsHandler,
::FirDumpHandler,
::FirCfgDumpHandler,
::FirCfgConsistencyHandler,
::FirResolvedTypesVerifier,
::FirScopeDumpHandler,
)
}
}
}
abstract class AbstractDiagnosticsFirWasmTest : AbstractFirWasmDiagnosticTestBase(FirParser.Psi)
@@ -0,0 +1,100 @@
/*
* 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.wasm.test.diagnostics;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.GenerateWasmTestsKt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("compiler/testData/diagnostics/wasmTests")
@TestDataPath("$PROJECT_ROOT")
public class DiagnosticsFirWasmTestGenerated extends AbstractDiagnosticsFirWasmTest {
@Test
public void testAllFilesPresentInWasmTests() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/wasmTests"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Nested
@TestMetadata("compiler/testData/diagnostics/wasmTests/jsInterop")
@TestDataPath("$PROJECT_ROOT")
public class JsInterop {
@Test
public void testAllFilesPresentInJsInterop() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/wasmTests/jsInterop"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("dynamicUnsupported.kt")
public void testDynamicUnsupported() throws Exception {
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/dynamicUnsupported.kt");
}
@Test
@TestMetadata("external.kt")
public void testExternal() throws Exception {
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/external.kt");
}
@Test
@TestMetadata("inheritance.kt")
public void testInheritance() throws Exception {
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/inheritance.kt");
}
@Test
@TestMetadata("jsCode.kt")
public void testJsCode() throws Exception {
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/jsCode.kt");
}
@Test
@TestMetadata("jsExport.kt")
public void testJsExport() throws Exception {
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/jsExport.kt");
}
@Test
@TestMetadata("jsFun.kt")
public void testJsFun() throws Exception {
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/jsFun.kt");
}
@Test
@TestMetadata("types.kt")
public void testTypes() throws Exception {
runTest("compiler/testData/diagnostics/wasmTests/jsInterop/types.kt");
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/wasmTests/wasmInterop")
@TestDataPath("$PROJECT_ROOT")
public class WasmInterop {
@Test
public void testAllFilesPresentInWasmInterop() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/wasmTests/wasmInterop"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("wasmExport.kt")
public void testWasmExport() throws Exception {
runTest("compiler/testData/diagnostics/wasmTests/wasmInterop/wasmExport.kt");
}
@Test
@TestMetadata("wasmImport.kt")
public void testWasmImport() throws Exception {
runTest("compiler/testData/diagnostics/wasmTests/wasmInterop/wasmImport.kt");
}
}
}
@@ -21,7 +21,7 @@ import java.util.regex.Pattern;
public class DiagnosticsWasmTestGenerated extends AbstractDiagnosticsWasmTest {
@Test
public void testAllFilesPresentInWasmTests() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/wasmTests"), Pattern.compile("^(.+)\\.kt$"), null, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/wasmTests"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Nested
@@ -30,7 +30,7 @@ public class DiagnosticsWasmTestGenerated extends AbstractDiagnosticsWasmTest {
public class JsInterop {
@Test
public void testAllFilesPresentInJsInterop() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/wasmTests/jsInterop"), Pattern.compile("^(.+)\\.kt$"), null, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/wasmTests/jsInterop"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@@ -82,7 +82,7 @@ public class DiagnosticsWasmTestGenerated extends AbstractDiagnosticsWasmTest {
public class WasmInterop {
@Test
public void testAllFilesPresentInWasmInterop() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/wasmTests/wasmInterop"), Pattern.compile("^(.+)\\.kt$"), null, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/wasmTests/wasmInterop"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test