From b03af384af53a0f707fd0f744d32b201c28d02c0 Mon Sep 17 00:00:00 2001 From: Ilya Goncharov Date: Tue, 15 Jun 2021 20:18:30 +0300 Subject: [PATCH] [JS IR] Add test with exception diagnostic of boolean in externals --- .../jetbrains/kotlin/js/test/BasicBoxTest.kt | 27 +++++++++- .../kotlin/js/test/BasicIrBoxTest.kt | 4 ++ .../semantics/IrBoxJsES6TestGenerated.java | 5 ++ .../ir/semantics/IrBoxJsTestGenerated.java | 5 ++ .../booleanInExternalsWithDiagnostic.kt | 50 +++++++++++++++++++ 5 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 js/js.translator/testData/box/propertyAccess/booleanInExternalsWithDiagnostic.kt diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt index 41a29c8d0d9..9e3823f3306 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt @@ -14,10 +14,12 @@ import com.intellij.psi.PsiManager import junit.framework.TestCase import org.jetbrains.kotlin.checkers.CompilerTestLanguageVersionSettings import org.jetbrains.kotlin.checkers.parseLanguageVersionSettings +import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.common.messages.MessageRenderer import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector import org.jetbrains.kotlin.cli.common.output.writeAllTo +import org.jetbrains.kotlin.cli.js.resolve import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.config.* @@ -151,6 +153,12 @@ abstract class BasicBoxTest( val propertyLazyInitialization = PROPERTY_LAZY_INITIALIZATION.matcher(fileContent).find() val safeExternalBoolean = SAFE_EXTERNAL_BOOLEAN.matcher(fileContent).find() + val safeExternalBooleanDiagnosticMatcher = SAFE_EXTERNAL_BOOLEAN_DIAGNOSTIC.matcher(fileContent) + + val safeExternalBooleanDiagnostic = + if (safeExternalBooleanDiagnosticMatcher.find()) + RuntimeDiagnostic.resolve(safeExternalBooleanDiagnosticMatcher.group(1)) + else null TestFileFactoryImpl().use { testFactory -> val inputFiles = TestFiles.createTestFiles( @@ -216,7 +224,8 @@ abstract class BasicBoxTest( splitPerModule, errorPolicy, propertyLazyInitialization, - safeExternalBoolean + safeExternalBoolean, + safeExternalBooleanDiagnostic, ) when { @@ -471,6 +480,7 @@ abstract class BasicBoxTest( errorIgnorancePolicy: ErrorTolerancePolicy, propertyLazyInitialization: Boolean, safeExternalBoolean: Boolean, + safeExternalBooleanDiagnostic: RuntimeDiagnostic?, ) { val kotlinFiles = module.files.filter { it.fileName.endsWith(".kt") } val testFiles = kotlinFiles.map { it.fileName } @@ -522,6 +532,7 @@ abstract class BasicBoxTest( splitPerModule, propertyLazyInitialization, safeExternalBoolean, + safeExternalBooleanDiagnostic, ) if (incrementalCompilationChecksEnabled && module.hasFilesToRecompile) { @@ -617,6 +628,7 @@ abstract class BasicBoxTest( splitPerModule = false, propertyLazyInitialization = false, safeExternalBoolean = false, + safeExternalBooleanDiagnostic = null, ) val originalOutput = FileUtil.loadFile(outputFile) @@ -697,6 +709,7 @@ abstract class BasicBoxTest( splitPerModule: Boolean, propertyLazyInitialization: Boolean, safeExternalBoolean: Boolean, + safeExternalBooleanDiagnostic: RuntimeDiagnostic?, ) { val translator = K2JSTranslator(config, false) val translationResult = translator.translateUnits(ExceptionThrowingReporter, units, mainCallParameters) @@ -1101,6 +1114,7 @@ abstract class BasicBoxTest( private val PROPERTY_LAZY_INITIALIZATION = Pattern.compile("^// *PROPERTY_LAZY_INITIALIZATION *$", Pattern.MULTILINE) private val SAFE_EXTERNAL_BOOLEAN = Pattern.compile("^// *SAFE_EXTERNAL_BOOLEAN *$", Pattern.MULTILINE) + private val SAFE_EXTERNAL_BOOLEAN_DIAGNOSTIC = Pattern.compile("^// *SAFE_EXTERNAL_BOOLEAN_DIAGNOSTIC: *(.+)$", Pattern.MULTILINE) @JvmStatic protected val runTestInNashorn = getBoolean("kotlin.js.useNashorn") @@ -1137,3 +1151,14 @@ class KotlinJsTestLogger { } } } + +fun RuntimeDiagnostic.Companion.resolve( + value: String?, +): RuntimeDiagnostic? = when (value?.lowercase()) { + K2JsArgumentConstants.RUNTIME_DIAGNOSTIC_LOG -> RuntimeDiagnostic.LOG + K2JsArgumentConstants.RUNTIME_DIAGNOSTIC_EXCEPTION -> RuntimeDiagnostic.EXCEPTION + null -> null + else -> { + null + } +} \ No newline at end of file diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt index 733121203a9..6d4d9811f7b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.config.JsConfig +import org.jetbrains.kotlin.js.config.RuntimeDiagnostic import org.jetbrains.kotlin.js.facade.MainCallParameters import org.jetbrains.kotlin.js.facade.TranslationUnit import org.jetbrains.kotlin.name.FqName @@ -96,6 +97,7 @@ abstract class BasicIrBoxTest( splitPerModule: Boolean, propertyLazyInitialization: Boolean, safeExternalBoolean: Boolean, + safeExternalBooleanDiagnostic: RuntimeDiagnostic?, ) { val filesToCompile = units.map { (it as TranslationUnit.SourceFile).file } @@ -153,6 +155,7 @@ abstract class BasicIrBoxTest( propertyLazyInitialization = propertyLazyInitialization, lowerPerModule = lowerPerModule, safeExternalBoolean = safeExternalBoolean, + safeExternalBooleanDiagnostic = safeExternalBooleanDiagnostic, ) compiledModule.jsCode!!.writeTo(outputFile, config) @@ -183,6 +186,7 @@ abstract class BasicIrBoxTest( multiModule = splitPerModule || perModule, propertyLazyInitialization = propertyLazyInitialization, safeExternalBoolean = safeExternalBoolean, + safeExternalBooleanDiagnostic = safeExternalBooleanDiagnostic, ).jsCode!!.writeTo(pirOutputFile, config) } } else { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrBoxJsES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrBoxJsES6TestGenerated.java index 394cfd14170..5cb3e13bd12 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrBoxJsES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrBoxJsES6TestGenerated.java @@ -6827,6 +6827,11 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test { runTest("js/js.translator/testData/box/propertyAccess/booleanInExternals.kt"); } + @TestMetadata("booleanInExternalsWithDiagnostic.kt") + public void testBooleanInExternalsWithDiagnostic() throws Exception { + runTest("js/js.translator/testData/box/propertyAccess/booleanInExternalsWithDiagnostic.kt"); + } + @TestMetadata("classUsesPackageProperties.kt") public void testClassUsesPackageProperties() throws Exception { runTest("js/js.translator/testData/box/propertyAccess/classUsesPackageProperties.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java index 21391fc8900..c8b26f7fb4a 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java @@ -6827,6 +6827,11 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { runTest("js/js.translator/testData/box/propertyAccess/booleanInExternals.kt"); } + @TestMetadata("booleanInExternalsWithDiagnostic.kt") + public void testBooleanInExternalsWithDiagnostic() throws Exception { + runTest("js/js.translator/testData/box/propertyAccess/booleanInExternalsWithDiagnostic.kt"); + } + @TestMetadata("classUsesPackageProperties.kt") public void testClassUsesPackageProperties() throws Exception { runTest("js/js.translator/testData/box/propertyAccess/classUsesPackageProperties.kt"); diff --git a/js/js.translator/testData/box/propertyAccess/booleanInExternalsWithDiagnostic.kt b/js/js.translator/testData/box/propertyAccess/booleanInExternalsWithDiagnostic.kt new file mode 100644 index 00000000000..e2d97300a6c --- /dev/null +++ b/js/js.translator/testData/box/propertyAccess/booleanInExternalsWithDiagnostic.kt @@ -0,0 +1,50 @@ +// TARGET_BACKEND: JS_IR +// SAFE_EXTERNAL_BOOLEAN_DIAGNOSTIC: EXCEPTION + +@JsName("Error") +internal open external class JsError(message: String) : Throwable + +fun box(): String { + val interfaceWithBoolean: InterfaceWithBoolean = js("{}") + try { + C().c = interfaceWithBoolean.foo + } catch (e: JsError) { + if (e.message.asDynamic().includes("Boolean expected for")) { + return "OK" + } + } + + return "fail" +} + +abstract class A { + open fun get(): T { + return this.asDynamic()["attr"].unsafeCast() + } + + open fun set(value: T) { + this.asDynamic()["attr"] = value + } +} + +class B : A() { + override fun set(value: Boolean) { + if (value) { + this.asDynamic()["attr"] = value + } + } +} + +val b: A = B() + +class C { + var c: Boolean + get() = b.get() + set(newValue) { + b.set(newValue) + } +} + +external interface InterfaceWithBoolean { + var foo: Boolean +} \ No newline at end of file