diff --git a/.gitignore b/.gitignore index f29f98b5108..120809d3411 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ kotstd/kotstd.iml *.kt.S *.kt.exe *.log +**/test-result.md # Ignore Gradle GUI config gradle-app.setting diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index 00ed3811ce4..1ee692920fa 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -1,3 +1,10 @@ +import com.google.common.collect.Lists +import groovy.io.FileType +import org.jetbrains.kotlin.* + +import java.nio.file.* +import java.util.regex.Matcher + configurations { cli_bc } @@ -6,109 +13,79 @@ dependencies { cli_bc project(path: ':backend.native', configuration: 'cli_bc') } +def logFileName = "test-result.md" +task regenerate_external_tests() { + doLast { + def externalTestsProject = childProjects["external"] + def gradleGenerated = externalTestsProject.file("build.gradle") + def externalTestsDir = externalTestsProject.file("codegen/blackbox") + gradleGenerated.write("import org.jetbrains.kotlin.*\n") + gradleGenerated.append( +""" +configurations { + cli_bc +} -abstract class KonanTest extends DefaultTask { - protected String source - def backendNative = project.project(":backend.native") - def runtimeProject = project.project(":runtime") - def dist = project.parent.parent.file("dist") - def llvmLlc = llvmTool("llc") - def runtimeBc = new File("${dist.canonicalPath}/lib/runtime.bc").absolutePath - def launcherBc = new File("${dist.canonicalPath}/lib/launcher.bc").absolutePath - def startKtBc = new File("${dist.canonicalPath}/lib/start.kt.bc").absolutePath - def stdlibKtBc = new File("${dist.canonicalPath}/lib/stdlib.kt.bc").absolutePath - def mainC = 'main.c' - String goldValue = null - String testData = null - List arguments = null - - boolean enabled = true - - public void setDisabled(boolean value) { - this.enabled = !value +dependencies { + cli_bc project(path: ':backend.native', configuration: 'cli_bc') +} +""" + ) + gradleGenerated.append( +""" +task createLogFile() { + doLast { + project.file("$logFileName").write("") } +} +""" + ) + externalTestsDir.eachDirRecurse { + // Skip build directory and directories without *.kt files. + if (it.name == "build" || it.listFiles().count {it.name.endsWith(".kt")} == 0) { + return + } - public KonanTest(){ - // TODO: that's a long reach up the project tree. - // May be we should reorganize a little. - dependsOn(project.parent.parent.tasks['dist']) - } + def taskDirectory = externalTestsProject.relativePath(it) + def taskName = taskDirectory.replaceAll("[-/]", '_') - abstract void compileTest(String source, String exe) - - protected void runCompiler(String source, String output, List moreArgs) { - project.javaexec { - main = 'org.jetbrains.kotlin.cli.bc.K2NativeKt' - classpath = project.configurations.cli_bc - jvmArgs "-ea", - "-Dkonan.home=${dist.canonicalPath}", - "-Djava.library.path=${dist.canonicalPath}/konan/nativelib" - args("-output", output, - source, - *moreArgs, - *project.globalArgs) + gradleGenerated.append( + "task $taskName (type: RunExternalTestGroup) {\n" + + " dependsOn(createLogFile)\n" + + " groupDirectory = \"$taskDirectory\"\n" + + " logFileName = \"$logFileName\"\n" + + "}\n\n") } } - - @TaskAction - void executeTest() { - def sourceKt = project.file(source).absolutePath - def exe = sourceKt.replace(".kt", ".kt.exe") - - compileTest(sourceKt, exe) - println "execution :$exe" - - def out = null - project.exec { - commandLine exe - if (arguments != null) { - args arguments - } - if (testData != null) { - standardInput = new ByteArrayInputStream(testData.bytes) - } - if (goldValue != null) { - out = new ByteArrayOutputStream() - standardOutput = out - } - } - if (goldValue != null && goldValue != out.toString()) - throw new RuntimeException("test failed") - } - - private String llvmTool(String tool) { - return "${project.llvmDir}/bin/${tool}" - } - - protected List clangLinkArgs() { - return project.clangLinkArgs - } } -class RunKonanTest extends KonanTest { - void compileTest(String source, String exe) { - runCompiler(source, exe, []) - } -} - -class LinkKonanTest extends KonanTest { - protected String lib - - void compileTest(String source, String exe) { - def libDir = project.file(lib).absolutePath - def libBc = "${libDir}.bc" - - runCompiler(lib, libBc, ['-nolink', '-nostdlib']) - runCompiler(source, exe, ['-library', libBc]) - } -} - - task run() { dependsOn(tasks.withType(KonanTest).matching { it.enabled }) } +task run_external () { + project.subprojects { + dependsOn(it.tasks.withType(RunExternalTestGroup).matching { it.enabled }) + } + doLast { + def logFile = childProjects["external"].file(logFileName) + def logText = logFile.text + + def passed = logText.count("|PASSED|") + def failed = logText.count("|FAILED|") + def skipped = logText.count("|SKIPPED|") + + def report = "\nDONE.\n\n" + + "PASSED: $passed\n" + + "FAILED: $failed\n" + + "TOTAL (FAILED + PASSED): ${passed + failed}\n" + + "SKIPPED : $skipped" + logFile.append(report) + println(report) + } +} + task sum (type:RunKonanTest) { source = "codegen/function/sum.kt" } diff --git a/backend.native/tests/external/build.gradle b/backend.native/tests/external/build.gradle new file mode 100644 index 00000000000..38639043b64 --- /dev/null +++ b/backend.native/tests/external/build.gradle @@ -0,0 +1,1215 @@ +import org.jetbrains.kotlin.* + +configurations { + cli_bc +} + +dependencies { + cli_bc project(path: ':backend.native', configuration: 'cli_bc') +} + +task createLogFile() { + doLast { + project.file("test-result.md").write("") + } +} +task codegen_blackbox_annotations (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/annotations" + logFileName = "test-result.md" +} + +task codegen_blackbox_annotations_annotatedLambda (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/annotations/annotatedLambda" + logFileName = "test-result.md" +} + +task codegen_blackbox_argumentOrder (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/argumentOrder" + logFileName = "test-result.md" +} + +task codegen_blackbox_arrays (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/arrays" + logFileName = "test-result.md" +} + +task codegen_blackbox_arrays_multiDecl (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/arrays/multiDecl" + logFileName = "test-result.md" +} + +task codegen_blackbox_arrays_multiDecl_int (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/arrays/multiDecl/int" + logFileName = "test-result.md" +} + +task codegen_blackbox_arrays_multiDecl_long (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/arrays/multiDecl/long" + logFileName = "test-result.md" +} + +task codegen_blackbox_binaryOp (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/binaryOp" + logFileName = "test-result.md" +} + +task codegen_blackbox_boxingOptimization (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/boxingOptimization" + logFileName = "test-result.md" +} + +task codegen_blackbox_bridges (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/bridges" + logFileName = "test-result.md" +} + +task codegen_blackbox_bridges_substitutionInSuperClass (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/bridges/substitutionInSuperClass" + logFileName = "test-result.md" +} + +task codegen_blackbox_builtinStubMethods (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/builtinStubMethods" + logFileName = "test-result.md" +} + +task codegen_blackbox_builtinStubMethods_extendJavaCollections (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/builtinStubMethods/extendJavaCollections" + logFileName = "test-result.md" +} + +task codegen_blackbox_callableReference_bound (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/callableReference/bound" + logFileName = "test-result.md" +} + +task codegen_blackbox_callableReference_bound_equals (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/callableReference/bound/equals" + logFileName = "test-result.md" +} + +task codegen_blackbox_callableReference_bound_inline (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/callableReference/bound/inline" + logFileName = "test-result.md" +} + +task codegen_blackbox_callableReference_function (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/callableReference/function" + logFileName = "test-result.md" +} + +task codegen_blackbox_callableReference_function_local (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/callableReference/function/local" + logFileName = "test-result.md" +} + +task codegen_blackbox_callableReference_property (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/callableReference/property" + logFileName = "test-result.md" +} + +task codegen_blackbox_casts (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/casts" + logFileName = "test-result.md" +} + +task codegen_blackbox_casts_functions (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/casts/functions" + logFileName = "test-result.md" +} + +task codegen_blackbox_casts_literalExpressionAsGenericArgument (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/casts/literalExpressionAsGenericArgument" + logFileName = "test-result.md" +} + +task codegen_blackbox_casts_mutableCollections (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/casts/mutableCollections" + logFileName = "test-result.md" +} + +task codegen_blackbox_classes (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/classes" + logFileName = "test-result.md" +} + +task codegen_blackbox_classes_inner (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/classes/inner" + logFileName = "test-result.md" +} + +task codegen_blackbox_classLiteral (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/classLiteral" + logFileName = "test-result.md" +} + +task codegen_blackbox_classLiteral_bound (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/classLiteral/bound" + logFileName = "test-result.md" +} + +task codegen_blackbox_classLiteral_java (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/classLiteral/java" + logFileName = "test-result.md" +} + +task codegen_blackbox_closures (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/closures" + logFileName = "test-result.md" +} + +task codegen_blackbox_closures_captureOuterProperty (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/closures/captureOuterProperty" + logFileName = "test-result.md" +} + +task codegen_blackbox_closures_closureInsideClosure (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/closures/closureInsideClosure" + logFileName = "test-result.md" +} + +task codegen_blackbox_collections (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/collections" + logFileName = "test-result.md" +} + +task codegen_blackbox_compatibility (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/compatibility" + logFileName = "test-result.md" +} + +task codegen_blackbox_constants (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/constants" + logFileName = "test-result.md" +} + +task codegen_blackbox_controlStructures (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/controlStructures" + logFileName = "test-result.md" +} + +task codegen_blackbox_controlStructures_breakContinueInExpressions (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/controlStructures/breakContinueInExpressions" + logFileName = "test-result.md" +} + +task codegen_blackbox_controlStructures_returnsNothing (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/controlStructures/returnsNothing" + logFileName = "test-result.md" +} + +task codegen_blackbox_controlStructures_tryCatchInExpressions (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/controlStructures/tryCatchInExpressions" + logFileName = "test-result.md" +} + +task codegen_blackbox_coroutines (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/coroutines" + logFileName = "test-result.md" +} + +task codegen_blackbox_coroutines_controlFlow (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/coroutines/controlFlow" + logFileName = "test-result.md" +} + +task codegen_blackbox_coroutines_intLikeVarSpilling (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/coroutines/intLikeVarSpilling" + logFileName = "test-result.md" +} + +task codegen_blackbox_coroutines_multiModule (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/coroutines/multiModule" + logFileName = "test-result.md" +} + +task codegen_blackbox_coroutines_stackUnwinding (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/coroutines/stackUnwinding" + logFileName = "test-result.md" +} + +task codegen_blackbox_coroutines_suspendFunctionTypeCall (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/coroutines/suspendFunctionTypeCall" + logFileName = "test-result.md" +} + +task codegen_blackbox_coroutines_unitTypeReturn (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/coroutines/unitTypeReturn" + logFileName = "test-result.md" +} + +task codegen_blackbox_dataClasses (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/dataClasses" + logFileName = "test-result.md" +} + +task codegen_blackbox_dataClasses_copy (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/dataClasses/copy" + logFileName = "test-result.md" +} + +task codegen_blackbox_dataClasses_equals (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/dataClasses/equals" + logFileName = "test-result.md" +} + +task codegen_blackbox_dataClasses_hashCode (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/dataClasses/hashCode" + logFileName = "test-result.md" +} + +task codegen_blackbox_dataClasses_toString (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/dataClasses/toString" + logFileName = "test-result.md" +} + +task codegen_blackbox_deadCodeElimination (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/deadCodeElimination" + logFileName = "test-result.md" +} + +task codegen_blackbox_defaultArguments (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/defaultArguments" + logFileName = "test-result.md" +} + +task codegen_blackbox_defaultArguments_constructor (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/defaultArguments/constructor" + logFileName = "test-result.md" +} + +task codegen_blackbox_defaultArguments_convention (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/defaultArguments/convention" + logFileName = "test-result.md" +} + +task codegen_blackbox_defaultArguments_function (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/defaultArguments/function" + logFileName = "test-result.md" +} + +task codegen_blackbox_defaultArguments_private (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/defaultArguments/private" + logFileName = "test-result.md" +} + +task codegen_blackbox_defaultArguments_signature (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/defaultArguments/signature" + logFileName = "test-result.md" +} + +task codegen_blackbox_delegatedProperty (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/delegatedProperty" + logFileName = "test-result.md" +} + +task codegen_blackbox_delegatedProperty_local (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/delegatedProperty/local" + logFileName = "test-result.md" +} + +task codegen_blackbox_delegatedProperty_provideDelegate (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/delegatedProperty/provideDelegate" + logFileName = "test-result.md" +} + +task codegen_blackbox_delegation (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/delegation" + logFileName = "test-result.md" +} + +task codegen_blackbox_destructuringDeclInLambdaParam (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/destructuringDeclInLambdaParam" + logFileName = "test-result.md" +} + +task codegen_blackbox_diagnostics_functions_inference (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/diagnostics/functions/inference" + logFileName = "test-result.md" +} + +task codegen_blackbox_diagnostics_functions_invoke_onObjects (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/diagnostics/functions/invoke/onObjects" + logFileName = "test-result.md" +} + +task codegen_blackbox_diagnostics_functions_tailRecursion (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/diagnostics/functions/tailRecursion" + logFileName = "test-result.md" +} + +task codegen_blackbox_diagnostics_vararg (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/diagnostics/vararg" + logFileName = "test-result.md" +} + +task codegen_blackbox_elvis (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/elvis" + logFileName = "test-result.md" +} + +task codegen_blackbox_enum (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/enum" + logFileName = "test-result.md" +} + +task codegen_blackbox_evaluate (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/evaluate" + logFileName = "test-result.md" +} + +task codegen_blackbox_exclExcl (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/exclExcl" + logFileName = "test-result.md" +} + +task codegen_blackbox_extensionFunctions (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/extensionFunctions" + logFileName = "test-result.md" +} + +task codegen_blackbox_extensionProperties (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/extensionProperties" + logFileName = "test-result.md" +} + +task codegen_blackbox_external (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/external" + logFileName = "test-result.md" +} + +task codegen_blackbox_fakeOverride (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/fakeOverride" + logFileName = "test-result.md" +} + +task codegen_blackbox_fieldRename (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/fieldRename" + logFileName = "test-result.md" +} + +task codegen_blackbox_finally (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/finally" + logFileName = "test-result.md" +} + +task codegen_blackbox_fullJdk (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/fullJdk" + logFileName = "test-result.md" +} + +task codegen_blackbox_fullJdk_native (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/fullJdk/native" + logFileName = "test-result.md" +} + +task codegen_blackbox_fullJdk_regressions (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/fullJdk/regressions" + logFileName = "test-result.md" +} + +task codegen_blackbox_functions (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/functions" + logFileName = "test-result.md" +} + +task codegen_blackbox_functions_functionExpression (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/functions/functionExpression" + logFileName = "test-result.md" +} + +task codegen_blackbox_functions_invoke (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/functions/invoke" + logFileName = "test-result.md" +} + +task codegen_blackbox_functions_localFunctions (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/functions/localFunctions" + logFileName = "test-result.md" +} + +task codegen_blackbox_hashPMap (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/hashPMap" + logFileName = "test-result.md" +} + +task codegen_blackbox_ieee754 (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/ieee754" + logFileName = "test-result.md" +} + +task codegen_blackbox_increment (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/increment" + logFileName = "test-result.md" +} + +task codegen_blackbox_innerNested (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/innerNested" + logFileName = "test-result.md" +} + +task codegen_blackbox_innerNested_superConstructorCall (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/innerNested/superConstructorCall" + logFileName = "test-result.md" +} + +task codegen_blackbox_instructions_swap (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/instructions/swap" + logFileName = "test-result.md" +} + +task codegen_blackbox_intrinsics (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/intrinsics" + logFileName = "test-result.md" +} + +task codegen_blackbox_javaInterop (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/javaInterop" + logFileName = "test-result.md" +} + +task codegen_blackbox_javaInterop_generics (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/javaInterop/generics" + logFileName = "test-result.md" +} + +task codegen_blackbox_javaInterop_notNullAssertions (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/javaInterop/notNullAssertions" + logFileName = "test-result.md" +} + +task codegen_blackbox_javaInterop_objectMethods (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/javaInterop/objectMethods" + logFileName = "test-result.md" +} + +task codegen_blackbox_jdk (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/jdk" + logFileName = "test-result.md" +} + +task codegen_blackbox_jvmField (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/jvmField" + logFileName = "test-result.md" +} + +task codegen_blackbox_jvmName (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/jvmName" + logFileName = "test-result.md" +} + +task codegen_blackbox_jvmName_fileFacades (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/jvmName/fileFacades" + logFileName = "test-result.md" +} + +task codegen_blackbox_jvmOverloads (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/jvmOverloads" + logFileName = "test-result.md" +} + +task codegen_blackbox_jvmStatic (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/jvmStatic" + logFileName = "test-result.md" +} + +task codegen_blackbox_labels (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/labels" + logFileName = "test-result.md" +} + +task codegen_blackbox_lazyCodegen (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/lazyCodegen" + logFileName = "test-result.md" +} + +task codegen_blackbox_lazyCodegen_optimizations (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/lazyCodegen/optimizations" + logFileName = "test-result.md" +} + +task codegen_blackbox_localClasses (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/localClasses" + logFileName = "test-result.md" +} + +task codegen_blackbox_mangling (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/mangling" + logFileName = "test-result.md" +} + +task codegen_blackbox_multiDecl (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/multiDecl" + logFileName = "test-result.md" +} + +task codegen_blackbox_multiDecl_forIterator (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/multiDecl/forIterator" + logFileName = "test-result.md" +} + +task codegen_blackbox_multiDecl_forIterator_longIterator (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/multiDecl/forIterator/longIterator" + logFileName = "test-result.md" +} + +task codegen_blackbox_multiDecl_forRange (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/multiDecl/forRange" + logFileName = "test-result.md" +} + +task codegen_blackbox_multiDecl_forRange_explicitRangeTo (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/multiDecl/forRange/explicitRangeTo" + logFileName = "test-result.md" +} + +task codegen_blackbox_multiDecl_forRange_explicitRangeTo_int (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/multiDecl/forRange/explicitRangeTo/int" + logFileName = "test-result.md" +} + +task codegen_blackbox_multiDecl_forRange_explicitRangeTo_long (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/multiDecl/forRange/explicitRangeTo/long" + logFileName = "test-result.md" +} + +task codegen_blackbox_multiDecl_forRange_explicitRangeToWithDot (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot" + logFileName = "test-result.md" +} + +task codegen_blackbox_multiDecl_forRange_explicitRangeToWithDot_int (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/int" + logFileName = "test-result.md" +} + +task codegen_blackbox_multiDecl_forRange_explicitRangeToWithDot_long (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/long" + logFileName = "test-result.md" +} + +task codegen_blackbox_multiDecl_forRange_int (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/multiDecl/forRange/int" + logFileName = "test-result.md" +} + +task codegen_blackbox_multiDecl_forRange_long (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/multiDecl/forRange/long" + logFileName = "test-result.md" +} + +task codegen_blackbox_multifileClasses (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/multifileClasses" + logFileName = "test-result.md" +} + +task codegen_blackbox_multifileClasses_optimized (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/multifileClasses/optimized" + logFileName = "test-result.md" +} + +task codegen_blackbox_nonLocalReturns (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/nonLocalReturns" + logFileName = "test-result.md" +} + +task codegen_blackbox_objectIntrinsics (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/objectIntrinsics" + logFileName = "test-result.md" +} + +task codegen_blackbox_objects (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/objects" + logFileName = "test-result.md" +} + +task codegen_blackbox_operatorConventions (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/operatorConventions" + logFileName = "test-result.md" +} + +task codegen_blackbox_operatorConventions_compareTo (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/operatorConventions/compareTo" + logFileName = "test-result.md" +} + +task codegen_blackbox_package (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/package" + logFileName = "test-result.md" +} + +task codegen_blackbox_platformTypes_primitives (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/platformTypes/primitives" + logFileName = "test-result.md" +} + +task codegen_blackbox_primitiveTypes (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/primitiveTypes" + logFileName = "test-result.md" +} + +task codegen_blackbox_private (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/private" + logFileName = "test-result.md" +} + +task codegen_blackbox_privateConstructors (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/privateConstructors" + logFileName = "test-result.md" +} + +task codegen_blackbox_properties (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/properties" + logFileName = "test-result.md" +} + +task codegen_blackbox_properties_const (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/properties/const" + logFileName = "test-result.md" +} + +task codegen_blackbox_properties_lateinit (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/properties/lateinit" + logFileName = "test-result.md" +} + +task codegen_blackbox_publishedApi (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/publishedApi" + logFileName = "test-result.md" +} + +task codegen_blackbox_ranges (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/ranges" + logFileName = "test-result.md" +} + +task codegen_blackbox_ranges_contains (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/ranges/contains" + logFileName = "test-result.md" +} + +task codegen_blackbox_ranges_expression (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/ranges/expression" + logFileName = "test-result.md" +} + +task codegen_blackbox_ranges_forInDownTo (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/ranges/forInDownTo" + logFileName = "test-result.md" +} + +task codegen_blackbox_ranges_forInIndices (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/ranges/forInIndices" + logFileName = "test-result.md" +} + +task codegen_blackbox_ranges_literal (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/ranges/literal" + logFileName = "test-result.md" +} + +task codegen_blackbox_ranges_nullableLoopParameter (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/ranges/nullableLoopParameter" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_annotations (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/annotations" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_call (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/call" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_call_bound (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/call/bound" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_callBy (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/callBy" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_classes (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/classes" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_classLiterals (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/classLiterals" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_constructors (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/constructors" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_createAnnotation (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/createAnnotation" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_enclosing (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/enclosing" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_functions (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/functions" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_genericSignature (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/genericSignature" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_isInstance (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/isInstance" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_kClassInAnnotation (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/kClassInAnnotation" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_lambdaClasses (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/lambdaClasses" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_mapping (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/mapping" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_mapping_fakeOverrides (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/mapping/fakeOverrides" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_mapping_jvmStatic (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/mapping/jvmStatic" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_mapping_types (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/mapping/types" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_methodsFromAny (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/methodsFromAny" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_modifiers (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/modifiers" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_multifileClasses (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/multifileClasses" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_noReflectAtRuntime (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/noReflectAtRuntime" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_noReflectAtRuntime_methodsFromAny (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/noReflectAtRuntime/methodsFromAny" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_parameters (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/parameters" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_properties (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/properties" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_properties_accessors (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/properties/accessors" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_specialBuiltIns (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/specialBuiltIns" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_supertypes (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/supertypes" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_typeParameters (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/typeParameters" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_types (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/types" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_types_createType (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/types/createType" + logFileName = "test-result.md" +} + +task codegen_blackbox_reflection_types_subtyping (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reflection/types/subtyping" + logFileName = "test-result.md" +} + +task codegen_blackbox_regressions (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/regressions" + logFileName = "test-result.md" +} + +task codegen_blackbox_reified (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reified" + logFileName = "test-result.md" +} + +task codegen_blackbox_reified_arraysReification (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/reified/arraysReification" + logFileName = "test-result.md" +} + +task codegen_blackbox_safeCall (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/safeCall" + logFileName = "test-result.md" +} + +task codegen_blackbox_sam_constructors (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/sam/constructors" + logFileName = "test-result.md" +} + +task codegen_blackbox_sealed (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/sealed" + logFileName = "test-result.md" +} + +task codegen_blackbox_secondaryConstructors (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/secondaryConstructors" + logFileName = "test-result.md" +} + +task codegen_blackbox_smap (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/smap" + logFileName = "test-result.md" +} + +task codegen_blackbox_smartCasts (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/smartCasts" + logFileName = "test-result.md" +} + +task codegen_blackbox_specialBuiltins (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/specialBuiltins" + logFileName = "test-result.md" +} + +task codegen_blackbox_statics (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/statics" + logFileName = "test-result.md" +} + +task codegen_blackbox_storeStackBeforeInline (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/storeStackBeforeInline" + logFileName = "test-result.md" +} + +task codegen_blackbox_strings (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/strings" + logFileName = "test-result.md" +} + +task codegen_blackbox_super (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/super" + logFileName = "test-result.md" +} + +task codegen_blackbox_synchronized (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/synchronized" + logFileName = "test-result.md" +} + +task codegen_blackbox_syntheticAccessors (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/syntheticAccessors" + logFileName = "test-result.md" +} + +task codegen_blackbox_toArray (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/toArray" + logFileName = "test-result.md" +} + +task codegen_blackbox_topLevelPrivate (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/topLevelPrivate" + logFileName = "test-result.md" +} + +task codegen_blackbox_traits (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/traits" + logFileName = "test-result.md" +} + +task codegen_blackbox_typealias (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/typealias" + logFileName = "test-result.md" +} + +task codegen_blackbox_typeInfo (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/typeInfo" + logFileName = "test-result.md" +} + +task codegen_blackbox_typeMapping (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/typeMapping" + logFileName = "test-result.md" +} + +task codegen_blackbox_unaryOp (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/unaryOp" + logFileName = "test-result.md" +} + +task codegen_blackbox_unit (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/unit" + logFileName = "test-result.md" +} + +task codegen_blackbox_vararg (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/vararg" + logFileName = "test-result.md" +} + +task codegen_blackbox_when (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/when" + logFileName = "test-result.md" +} + +task codegen_blackbox_when_enumOptimization (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/when/enumOptimization" + logFileName = "test-result.md" +} + +task codegen_blackbox_when_stringOptimization (type: RunExternalTestGroup) { + dependsOn(createLogFile) + groupDirectory = "codegen/blackbox/when/stringOptimization" + logFileName = "test-result.md" +} + diff --git a/backend.native/tests/external/codegen/blackbox/annotations/annotatedEnumEntry.kt b/backend.native/tests/external/codegen/blackbox/annotations/annotatedEnumEntry.kt new file mode 100644 index 00000000000..37f0de4e7c2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/annotatedEnumEntry.kt @@ -0,0 +1,35 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// KT-5665 + +@Retention(AnnotationRetention.RUNTIME) +annotation class First + +@Retention(AnnotationRetention.RUNTIME) +annotation class Second(val value: String) + +enum class E { + @First + E1 { + fun foo() = "something" + }, + + @Second("OK") + E2 +} + +fun box(): String { + val e = E::class.java + + val e1 = e.getDeclaredField(E.E1.toString()).getAnnotations() + if (e1.size != 1) return "Fail E1 size: ${e1.toList()}" + if (e1[0].annotationClass.java != First::class.java) return "Fail E1: ${e1.toList()}" + + val e2 = e.getDeclaredField(E.E2.toString()).getAnnotations() + if (e2.size != 1) return "Fail E2 size: ${e2.toList()}" + if (e2[0].annotationClass.java != Second::class.java) return "Fail E2: ${e2.toList()}" + + return (e2[0] as Second).value +} diff --git a/backend.native/tests/external/codegen/blackbox/annotations/annotatedLambda/funExpression.kt b/backend.native/tests/external/codegen/blackbox/annotations/annotatedLambda/funExpression.kt new file mode 100644 index 00000000000..d8f6b4fce94 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/annotatedLambda/funExpression.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import java.lang.reflect.Method +import kotlin.test.assertEquals + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann(val x: String) + +fun foo0(block: () -> Unit) = block.javaClass +fun foo1(block: (String) -> Unit) = block.javaClass + +fun testMethod(method: Method, name: String) { + assertEquals("OK", method.getAnnotation(Ann::class.java).x, "On method of test named `$name`") + + for ((index, annotations) in method.getParameterAnnotations().withIndex()) { + val ann = annotations.filterIsInstance().single() + assertEquals("OK$index", ann.x, "On parameter $index of test named `$name`") + } +} + +fun testClass(clazz: Class<*>, name: String) { + val invokes = clazz.getDeclaredMethods().single() { !it.isBridge() } + testMethod(invokes, name) +} + +fun box(): String { + testClass(foo0( @Ann("OK") fun() {} ), "1") + testClass(foo1( @Ann("OK") fun(@Ann("OK0") x: String) {} ), "2") + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/annotations/annotatedLambda/lambda.kt b/backend.native/tests/external/codegen/blackbox/annotations/annotatedLambda/lambda.kt new file mode 100644 index 00000000000..67bea1e84ea --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/annotatedLambda/lambda.kt @@ -0,0 +1,35 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import java.lang.reflect.Method +import kotlin.test.assertEquals + +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann(val x: String) + +fun foo0(block: () -> Unit) = block.javaClass + +fun testMethod(method: Method, name: String) { + assertEquals("OK", method.getAnnotation(Ann::class.java).x, "On method of test named `$name`") + + for ((index, annotations) in method.getParameterAnnotations().withIndex()) { + val ann = annotations.filterIsInstance().single() + assertEquals("OK$index", ann.x, "On parameter $index of test named `$name`") + } +} + +fun testClass(clazz: Class<*>, name: String) { + val invokes = clazz.getDeclaredMethods().single() { !it.isBridge() } + testMethod(invokes, name) +} + +fun box(): String { + testClass(foo0(@Ann("OK") { }), "1") + testClass(foo0( @Ann("OK") { }), "2") + + testClass(foo0() @Ann("OK") { }, "3") + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/annotations/annotatedLambda/samFunExpression.kt b/backend.native/tests/external/codegen/blackbox/annotations/annotatedLambda/samFunExpression.kt new file mode 100644 index 00000000000..0e03694d6a9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/annotatedLambda/samFunExpression.kt @@ -0,0 +1,49 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Test.java + +class Test { + public static Class apply(Runnable x) { + return x.getClass(); + } + + public static interface ABC { + void apply(String x1, String x2); + } + + public static Class applyABC(ABC x) { + return x.getClass(); + } +} + +// FILE: test.kt + +import java.lang.reflect.Method +import kotlin.test.assertEquals + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann(val x: String) + +fun testMethod(method: Method, name: String) { + assertEquals("OK", method.getAnnotation(Ann::class.java).x, "On method of test named `$name`") + + for ((index, annotations) in method.getParameterAnnotations().withIndex()) { + val ann = annotations.filterIsInstance().single() + assertEquals("OK$index", ann.x, "On parameter $index of test named `$name`") + } +} + +fun testClass(clazz: Class<*>, name: String) { + val invokes = clazz.getDeclaredMethods().single() { !it.isBridge() } + testMethod(invokes, name) +} + +fun box(): String { + testClass(Test.apply(@Ann("OK") fun(){}), "1") + + testClass(Test.applyABC(@Ann("OK") fun(@Ann("OK0") x: String, @Ann("OK1") y: String){}), "2") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/annotations/annotatedLambda/samLambda.kt b/backend.native/tests/external/codegen/blackbox/annotations/annotatedLambda/samLambda.kt new file mode 100644 index 00000000000..382c6902ce9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/annotatedLambda/samLambda.kt @@ -0,0 +1,40 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Test.java + +class Test { + public static Class apply(Runnable x) { + return x.getClass(); + } +} + +// FILE: test.kt + +import java.lang.reflect.Method +import kotlin.test.assertEquals + +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann(val x: String) + +fun testMethod(method: Method, name: String) { + assertEquals("OK", method.getAnnotation(Ann::class.java).x, "On method of test named `$name`") + + for ((index, annotations) in method.getParameterAnnotations().withIndex()) { + val ann = annotations.filterIsInstance().single() + assertEquals("OK$index", ann.x, "On parameter $index of test named `$name`") + } +} + +fun testClass(clazz: Class<*>, name: String) { + val invokes = clazz.getDeclaredMethods().single() { !it.isBridge() } + testMethod(invokes, name) +} + +fun box(): String { + testClass(Test.apply(@Ann("OK") {}), "1") + testClass(Test.apply @Ann("OK") {}, "2") + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/annotations/annotatedObjectLiteral.kt b/backend.native/tests/external/codegen/blackbox/annotations/annotatedObjectLiteral.kt new file mode 100644 index 00000000000..0fba694eb67 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/annotatedObjectLiteral.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +annotation class Ann(val v: String = "???") +@Ann open class My +fun box(): String { + val v = @Ann("OK") object: My() {} + val klass = v.javaClass + + val annotations = klass.annotations.toList() + // Ann, kotlin.Metadata + if (annotations.size != 2) return "Fail annotations size is ${annotations.size}: $annotations" + val annotation = annotations.filterIsInstance().firstOrNull() + ?: return "Fail no @Ann: $annotations" + + return annotation.v +} diff --git a/backend.native/tests/external/codegen/blackbox/annotations/annotationWithKotlinProperty.kt b/backend.native/tests/external/codegen/blackbox/annotations/annotationWithKotlinProperty.kt new file mode 100644 index 00000000000..5f01b7eb25d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/annotationWithKotlinProperty.kt @@ -0,0 +1,36 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: JavaClass.java + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +public class JavaClass { + + @Retention(RetentionPolicy.RUNTIME) + @interface Foo { + int value(); + } + + @Foo(KotlinClass.FOO_INT) + public String test() throws NoSuchMethodException { + return KotlinClass.FOO_STRING + + JavaClass.class.getMethod("test").getAnnotation(Foo.class).value(); + } +} + +// FILE: kotlinClass.kt + +class KotlinClass { + companion object { + const val FOO_INT: Int = 10 + @JvmField val FOO_STRING: String = "OK" + } +} + +fun box(): String { + val test = JavaClass().test() + return if (test == "OK10") "OK" else "fail : $test" +} diff --git a/backend.native/tests/external/codegen/blackbox/annotations/annotationWithKotlinPropertyFromInterfaceCompanion.kt b/backend.native/tests/external/codegen/blackbox/annotations/annotationWithKotlinPropertyFromInterfaceCompanion.kt new file mode 100644 index 00000000000..74c8a7cbfff --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/annotationWithKotlinPropertyFromInterfaceCompanion.kt @@ -0,0 +1,35 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: JavaClass.java + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +public class JavaClass { + + @Retention(RetentionPolicy.RUNTIME) + @interface Foo { + int value(); + } + + @Foo(KotlinInterface.FOO_INT) + public String test() throws NoSuchMethodException { + return KotlinInterface.FOO_STRING + + JavaClass.class.getMethod("test").getAnnotation(Foo.class).value(); + } +} + +// FILE: KotlinInterface.kt + +interface KotlinInterface { + companion object { + const val FOO_INT: Int = 10 + const val FOO_STRING: String = "OK" + } +} + +fun box(): String { + val test = JavaClass().test() + return if (test == "OK10") "OK" else "fail : $test" +} diff --git a/backend.native/tests/external/codegen/blackbox/annotations/annotationsOnDefault.kt b/backend.native/tests/external/codegen/blackbox/annotations/annotationsOnDefault.kt new file mode 100644 index 00000000000..d9f682c8a55 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/annotationsOnDefault.kt @@ -0,0 +1,40 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann(val x: Int) +class A { + @Ann(1) fun foo(x: Int, y: Int = 2, z: Int) {} + + @Ann(1) constructor(x: Int, y: Int = 2, z: Int) +} + +class B @Ann(1) constructor(x: Int, y: Int = 2, z: Int) {} + +fun test(name: String, annotations: Array) { + assertEquals(1, annotations.filterIsInstance().single().x, "$name[0]") +} + +fun box(): String { + val foo = A::class.java.getDeclaredMethods().first { it.getName() == "foo" } + test("foo", foo.getDeclaredAnnotations()) + + val fooDefault = A::class.java.getDeclaredMethods().first { it.getName() == "foo\$default" } + test("foo", foo.getDeclaredAnnotations()) + + val (secondary, secondaryDefault) = A::class.java.getDeclaredConstructors().partition { it.getParameterTypes().size == 3 } + + test("secondary", secondary[0].getDeclaredAnnotations()) + test("secondary\$default", secondaryDefault[0].getDeclaredAnnotations()) + + val (primary, primaryDefault) = B::class.java.getConstructors().partition { it.getParameterTypes().size == 3 } + + test("primary", primary[0].getDeclaredAnnotations()) + test("primary\$default", primaryDefault[0].getDeclaredAnnotations()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/annotations/annotationsOnTypeAliases.kt b/backend.native/tests/external/codegen/blackbox/annotations/annotationsOnTypeAliases.kt new file mode 100644 index 00000000000..497fa723e09 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/annotationsOnTypeAliases.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +import kotlin.annotation.AnnotationTarget.* +import kotlin.annotation.AnnotationRetention.* +import java.lang.Class + +@Target(TYPEALIAS) +@Retention(RUNTIME) +annotation class Ann(val x: Int) + +@Ann(2) +typealias TA = Any + +fun Class<*>.assertHasDeclaredMethodWithAnn() { + if (!declaredMethods.any { it.isSynthetic && it.getAnnotation(Ann::class.java) != null }) { + throw java.lang.AssertionError("Class ${this.simpleName} has no declared method with annotation @Ann") + } +} + +fun box(): String { + Class.forName("AnnotationsOnTypeAliasesKt").assertHasDeclaredMethodWithAnn() + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/annotations/defaultParameterValues.kt b/backend.native/tests/external/codegen/blackbox/annotations/defaultParameterValues.kt new file mode 100644 index 00000000000..6987d370f5d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/defaultParameterValues.kt @@ -0,0 +1,41 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.reflect.KClass + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann( + val i: Int = 1, + val s: String = "a", + val a: Ann2 = Ann2(), + val e: MyEnum = MyEnum.A, + val c: KClass<*> = A::class, + val ia: IntArray = intArrayOf(1, 2), + val sa: Array = arrayOf("a", "b") +) + +fun box(): String { + val ann = MyClass::class.java.getAnnotation(Ann::class.java) + if (ann == null) return "fail: cannot find Ann on MyClass}" + if (ann.i != 1) return "fail: annotation parameter i should be 1, but was ${ann.i}" + if (ann.s != "a") return "fail: annotation parameter s should be \"a\", but was ${ann.s}" + val annSimpleName = ann.a.annotationClass.java.getSimpleName() + if (annSimpleName != "Ann2") return "fail: annotation parameter a should be of class Ann2, but was $annSimpleName" + if (ann.e != MyEnum.A) return "fail: annotation parameter e should be MyEnum.A, but was ${ann.e}" + if (ann.c.java != A::class.java) return "fail: annotation parameter c should be of class A, but was ${ann.c}" + if (ann.ia[0] != 1 || ann.ia[1] != 2) return "fail: annotation parameter ia should be [1, 2], but was ${ann.ia}" + if (ann.sa[0] != "a" || ann.sa[1] != "b") return "fail: annotation parameter ia should be [\"a\", \"b\"], but was ${ann.sa}" + return "OK" +} + +annotation class Ann2 + +enum class MyEnum { + A +} + +class A + +@Ann class MyClass diff --git a/backend.native/tests/external/codegen/blackbox/annotations/delegatedPropertySetter.kt b/backend.native/tests/external/codegen/blackbox/annotations/delegatedPropertySetter.kt new file mode 100644 index 00000000000..1abfbda2f9f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/delegatedPropertySetter.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.reflect.KProperty + +@Retention(AnnotationRetention.RUNTIME) +annotation class First + +class MyClass() { + public var x: String by Delegate() + @First set +} + +class Delegate { + operator fun getValue(t: Any?, p: KProperty<*>): String { + return "OK" + } + + operator fun setValue(t: Any?, p: KProperty<*>, i: String) {} +} + +fun box(): String { + val e = MyClass::class.java + + val e1 = e.getDeclaredMethod("setX", String::class.java).getAnnotations() + if (e1.size != 1) return "Fail E1 size: ${e1.toList()}" + if (e1[0].annotationClass.java != First::class.java) return "Fail: ${e1.toList()}" + + return MyClass().x +} diff --git a/backend.native/tests/external/codegen/blackbox/annotations/fileClassWithFileAnnotation.kt b/backend.native/tests/external/codegen/blackbox/annotations/fileClassWithFileAnnotation.kt new file mode 100644 index 00000000000..c33bb1b4c8d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/fileClassWithFileAnnotation.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@file:StringHolder("OK") +@file:JvmName("FileClass") + +@Target(AnnotationTarget.FILE) +@Retention(AnnotationRetention.RUNTIME) +public annotation class StringHolder(val value: String) + +fun box(): String = + Class.forName("FileClass").getAnnotation(StringHolder::class.java)?.value ?: "null" diff --git a/backend.native/tests/external/codegen/blackbox/annotations/jvmAnnotationFlags.kt b/backend.native/tests/external/codegen/blackbox/annotations/jvmAnnotationFlags.kt new file mode 100644 index 00000000000..fb5282b64df --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/jvmAnnotationFlags.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +import java.lang.reflect.Modifier +import kotlin.reflect.KProperty + +class CustomDelegate { + operator fun getValue(thisRef: Any?, prop: KProperty<*>): String = prop.name +} + +class C { + @Volatile var vol = 1 + @Transient val tra = 1 + @delegate:Transient val del: String by CustomDelegate() + + @Strictfp fun str() {} + @Synchronized fun sync() {} +} + +fun box(): String { + val c = C::class.java + + if (c.getDeclaredField("vol").getModifiers() and Modifier.VOLATILE == 0) return "Fail: volatile" + if (c.getDeclaredField("tra").getModifiers() and Modifier.TRANSIENT == 0) return "Fail: transient" + if (c.getDeclaredField("del\$delegate").getModifiers() and Modifier.TRANSIENT == 0) return "Fail: delegate transient" + + if (c.getDeclaredMethod("str").getModifiers() and Modifier.STRICT == 0) return "Fail: strict" + if (c.getDeclaredMethod("sync").getModifiers() and Modifier.SYNCHRONIZED == 0) return "Fail: synchronized" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/annotations/kotlinPropertyFromClassObjectAsParameter.kt b/backend.native/tests/external/codegen/blackbox/annotations/kotlinPropertyFromClassObjectAsParameter.kt new file mode 100644 index 00000000000..1d2eb2eec5c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/kotlinPropertyFromClassObjectAsParameter.kt @@ -0,0 +1,48 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Ann(Foo.i, Foo.s, Foo.f, Foo.d, Foo.l, Foo.b, Foo.bool, Foo.c, Foo.str) class MyClass + +fun box(): String { + val ann = MyClass::class.java.getAnnotation(Ann::class.java) + if (ann == null) return "fail: cannot find Ann on MyClass}" + if (ann.i != 2) return "fail: annotation parameter i should be 2, but was ${ann.i}" + if (ann.s != 2.toShort()) return "fail: annotation parameter i should be 2, but was ${ann.i}" + if (ann.f != 2.toFloat()) return "fail: annotation parameter i should be 2, but was ${ann.i}" + if (ann.d != 2.toDouble()) return "fail: annotation parameter i should be 2, but was ${ann.i}" + if (ann.l != 2.toLong()) return "fail: annotation parameter i should be 2, but was ${ann.i}" + if (ann.b != 2.toByte()) return "fail: annotation parameter i should be 2, but was ${ann.i}" + if (!ann.bool) return "fail: annotation parameter i should be true, but was ${ann.i}" + if (ann.c != 'c') return "fail: annotation parameter i should be c, but was ${ann.i}" + if (ann.str != "str") return "fail: annotation parameter i should be str, but was ${ann.i}" + return "OK" +} + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann( + val i: Int, + val s: Short, + val f: Float, + val d: Double, + val l: Long, + val b: Byte, + val bool: Boolean, + val c: Char, + val str: String +) + +class Foo { + companion object { + const val i: Int = 2 + const val s: Short = 2 + const val f: Float = 2.0.toFloat() + const val d: Double = 2.0 + const val l: Long = 2 + const val b: Byte = 2 + const val bool: Boolean = true + const val c: Char = 'c' + const val str: String = "str" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/annotations/kotlinTopLevelPropertyAsParameter.kt b/backend.native/tests/external/codegen/blackbox/annotations/kotlinTopLevelPropertyAsParameter.kt new file mode 100644 index 00000000000..4a2fda75c19 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/kotlinTopLevelPropertyAsParameter.kt @@ -0,0 +1,44 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Ann(i, s, f, d, l, b, bool, c, str) class MyClass + +fun box(): String { + val ann = MyClass::class.java.getAnnotation(Ann::class.java) + if (ann == null) return "fail: cannot find Ann on MyClass}" + if (ann.i != 2) return "fail: annotation parameter i should be 2, but was ${ann.i}" + if (ann.s != 2.toShort()) return "fail: annotation parameter i should be 2, but was ${ann.i}" + if (ann.f != 2.toFloat()) return "fail: annotation parameter i should be 2, but was ${ann.i}" + if (ann.d != 2.toDouble()) return "fail: annotation parameter i should be 2, but was ${ann.i}" + if (ann.l != 2.toLong()) return "fail: annotation parameter i should be 2, but was ${ann.i}" + if (ann.b != 2.toByte()) return "fail: annotation parameter i should be 2, but was ${ann.i}" + if (!ann.bool) return "fail: annotation parameter i should be true, but was ${ann.i}" + if (ann.c != 'c') return "fail: annotation parameter i should be c, but was ${ann.i}" + if (ann.str != "str") return "fail: annotation parameter i should be str, but was ${ann.i}" + return "OK" +} + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann( + val i: Int, + val s: Short, + val f: Float, + val d: Double, + val l: Long, + val b: Byte, + val bool: Boolean, + val c: Char, + val str: String +) + +const val i: Int = 2 +const val s: Short = 2 +const val f: Float = 2.0.toFloat() +const val d: Double = 2.0 +const val l: Long = 2 +const val b: Byte = 2 +const val bool: Boolean = true +const val c: Char = 'c' +const val str: String = "str" diff --git a/backend.native/tests/external/codegen/blackbox/annotations/kt10136.kt b/backend.native/tests/external/codegen/blackbox/annotations/kt10136.kt new file mode 100644 index 00000000000..c0481095c75 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/kt10136.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +annotation class A + +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +annotation class B(val items: Array = arrayOf(A())) + +@B +class C + +fun box(): String { + val bClass = B::class.java + val cClass = C::class.java + + val items = cClass.getAnnotation(bClass).items + assert(items.size == 1) { "Expected: [A()], got ${items.asList()}" } + assert(items[0] is A) { "Expected: [A()], got ${items.asList()}" } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/annotations/nestedClassPropertyAsParameter.kt b/backend.native/tests/external/codegen/blackbox/annotations/nestedClassPropertyAsParameter.kt new file mode 100644 index 00000000000..20ce394faf4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/nestedClassPropertyAsParameter.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Ann(A.B.i) class MyClass + +fun box(): String { + val ann = MyClass::class.java.getAnnotation(Ann::class.java) + if (ann == null) return "fail: cannot find Ann on MyClass}" + if (ann.i != 1) return "fail: annotation parameter i should be 1, but was ${ann.i}" + return "OK" +} + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann(val i: Int) + +class A { + class B { + companion object { + const val i = 1 + } + } +} diff --git a/backend.native/tests/external/codegen/blackbox/annotations/parameterWithPrimitiveType.kt b/backend.native/tests/external/codegen/blackbox/annotations/parameterWithPrimitiveType.kt new file mode 100644 index 00000000000..ac5be1259a4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/parameterWithPrimitiveType.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann( + val b: Byte, + val s: Short, + val i: Int, + val f: Float, + val d: Double, + val l: Long, + val c: Char, + val bool: Boolean +) + +fun box(): String { + val ann = MyClass::class.java.getAnnotation(Ann::class.java) + if (ann == null) return "fail: cannot find Ann on MyClass}" + if (ann.b != 1.toByte()) return "fail: annotation parameter b should be 1, but was ${ann.b}" + if (ann.s != 1.toShort()) return "fail: annotation parameter s should be 1, but was ${ann.s}" + if (ann.i != 1) return "fail: annotation parameter i should be 1, but was ${ann.i}" + if (ann.f != 1.toFloat()) return "fail: annotation parameter f should be 1, but was ${ann.f}" + if (ann.d != 1.0) return "fail: annotation parameter d should be 1, but was ${ann.d}" + if (ann.l != 1.toLong()) return "fail: annotation parameter l should be 1, but was ${ann.l}" + if (ann.c != 'c') return "fail: annotation parameter c should be 1, but was ${ann.c}" + if (!ann.bool) return "fail: annotation parameter bool should be 1, but was ${ann.bool}" + return "OK" +} + +@Ann(1, 1, 1, 1.0.toFloat(), 1.0, 1, 'c', true) class MyClass diff --git a/backend.native/tests/external/codegen/blackbox/annotations/propertyWithPropertyInInitializerAsParameter.kt b/backend.native/tests/external/codegen/blackbox/annotations/propertyWithPropertyInInitializerAsParameter.kt new file mode 100644 index 00000000000..167f2774238 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/propertyWithPropertyInInitializerAsParameter.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Ann(i) class MyClass + +fun box(): String { + val ann = MyClass::class.java.getAnnotation(Ann::class.java) + if (ann == null) return "fail: cannot find Ann on MyClass}" + if (ann.i != 1) return "fail: annotation parameter i should be 1, but was ${ann.i}" + return "OK" +} + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann(val i: Int) + +const val i2: Int = 1 +const val i: Int = i2 diff --git a/backend.native/tests/external/codegen/blackbox/annotations/resolveWithLowPriorityAnnotation.kt b/backend.native/tests/external/codegen/blackbox/annotations/resolveWithLowPriorityAnnotation.kt new file mode 100644 index 00000000000..9b51c9fdb51 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/resolveWithLowPriorityAnnotation.kt @@ -0,0 +1,19 @@ +// WITH_RUNTIME + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@kotlin.internal.LowPriorityInOverloadResolution +fun foo(i: Int) = 1 + +fun foo(a: Any) = 2 + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@kotlin.internal.LowPriorityInOverloadResolution +fun bar(a: String?) = 3 + +fun bar(a: Any) = 4 + +fun box(): String { + if (foo(1) != 2) return "fail1" + if (bar(null) != 3) return "fail2" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/annotations/varargInAnnotationParameter.kt b/backend.native/tests/external/codegen/blackbox/annotations/varargInAnnotationParameter.kt new file mode 100644 index 00000000000..2c21161ee08 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/annotations/varargInAnnotationParameter.kt @@ -0,0 +1,53 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann(vararg val p: Int) + +@Ann() class MyClass1 +@Ann(1) class MyClass2 +@Ann(1, 2) class MyClass3 + +@Ann(*intArrayOf()) class MyClass4 +@Ann(*intArrayOf(1)) class MyClass5 +@Ann(*intArrayOf(1, 2)) class MyClass6 + +@Ann(p = 1) class MyClass7 + +@Ann(p = *intArrayOf()) class MyClass8 +@Ann(p = *intArrayOf(1)) class MyClass9 +@Ann(p = *intArrayOf(1, 2)) class MyClass10 + +fun box(): String { + test(MyClass1::class.java, "") + test(MyClass2::class.java, "1") + test(MyClass3::class.java, "12") + + test(MyClass4::class.java, "") + test(MyClass5::class.java, "1") + test(MyClass6::class.java, "12") + + test(MyClass7::class.java, "1") + + test(MyClass8::class.java, "") + test(MyClass9::class.java, "1") + test(MyClass10::class.java, "12") + + return "OK" +} + +fun test(klass: Class<*>, expected: String) { + val ann = klass.getAnnotation(Ann::class.java) + if (ann == null) throw AssertionError("fail: cannot find Ann on ${klass}") + + var result = "" + for (i in ann.p) { + result += i + } + + if (result != expected) { + throw AssertionError("fail: expected = ${expected}, actual = ${result}") + } +} diff --git a/backend.native/tests/external/codegen/blackbox/argumentOrder/arguments.kt b/backend.native/tests/external/codegen/blackbox/argumentOrder/arguments.kt new file mode 100644 index 00000000000..d686101b1c7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/argumentOrder/arguments.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + + +fun test(a: String, b: String): String { + return a + b; +} + +fun box(): String { + var res = ""; + val call = test(b = {res += "K"; "K"}(), a = {res+="O"; "O"}()) + + if (res != "KO" || call != "OK") return "fail: $res != KO or $call != OK" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/argumentOrder/captured.kt b/backend.native/tests/external/codegen/blackbox/argumentOrder/captured.kt new file mode 100644 index 00000000000..99792dc416c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/argumentOrder/captured.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + var invokeOrder = ""; + val expectedResult = "0_1_9" + val expectedInvokeOrder = "1_0_9" + var l = 1L + var i = 0 + val captured = 9L + + var result = test(b = {invokeOrder += "1_"; l}(), a = {invokeOrder+="0_"; i}(), c = {invokeOrder += "$captured"; "$captured"}) + if (invokeOrder != expectedInvokeOrder || result != expectedResult) return "fail 1: $invokeOrder != $expectedInvokeOrder or $result != $expectedResult" + + invokeOrder = ""; + result = test(b = {invokeOrder += "1_"; l}(), c = {invokeOrder += "$captured"; "$captured"}, a = {invokeOrder+="0_"; i}()) + if (invokeOrder != expectedInvokeOrder || result != expectedResult) return "fail 2: $invokeOrder != $expectedInvokeOrder or $result != $expectedResult" + + + invokeOrder = ""; + result = test(c = {invokeOrder += "$captured"; "$captured"}, b = {invokeOrder += "1_"; l}(), a = {invokeOrder+="0_"; i}()) + if (invokeOrder != expectedInvokeOrder || result != expectedResult) return "fail 3: $invokeOrder != $expectedInvokeOrder or $result != $expectedResult" + + + invokeOrder = ""; + result = test(a = {invokeOrder+="0_"; i}(), c = {invokeOrder += "$captured"; "$captured"}, b = {invokeOrder += "1_"; l}()) + if (invokeOrder != "0_1_9" || result != expectedResult) return "fail 4: $invokeOrder != 0_1_9 or $result != $expectedResult" + + return "OK" +} + +fun test(a: Int, b: Long, c: () -> String): String { + return { "${a}_${b}_${c()}"} () +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/argumentOrder/capturedInExtension.kt b/backend.native/tests/external/codegen/blackbox/argumentOrder/capturedInExtension.kt new file mode 100644 index 00000000000..72ed6b1c2bc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/argumentOrder/capturedInExtension.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + var invokeOrder = ""; + val expectedResult = "1.0_0_1_9" + val expectedInvokeOrder = "1_0_9" + var l = 1L + var i = 0 + val captured = 9L + + var result = 1.0.test(b = {invokeOrder += "1_"; l}(), a = {invokeOrder+="0_"; i}(), c = {invokeOrder += "$captured"; "$captured"}) + if (invokeOrder != expectedInvokeOrder || result != expectedResult) return "fail 1: $invokeOrder != $expectedInvokeOrder or $result != $expectedResult" + + invokeOrder = ""; + result = 1.0.test(b = {invokeOrder += "1_"; l}(), c = {invokeOrder += "${captured}"; "${captured}"}, a = {invokeOrder+="0_"; i}()) + if (invokeOrder != expectedInvokeOrder || result != expectedResult) return "fail 2: $invokeOrder != $expectedInvokeOrder or $result != $expectedResult" + + + invokeOrder = ""; + result = 1.0.test(c = {invokeOrder += "${captured}"; "${captured}"}, b = {invokeOrder += "1_"; l}(), a = {invokeOrder+="0_"; i}()) + if (invokeOrder != expectedInvokeOrder || result != expectedResult) return "fail 3: $invokeOrder != $expectedInvokeOrder or $result != $expectedResult" + + invokeOrder = ""; + result = 1.0.test(a = {invokeOrder+="0_"; i}(), c = {invokeOrder += "${captured}"; "${captured}"}, b = {invokeOrder += "1_"; l}()) + if (invokeOrder != "0_1_9" || result != expectedResult) return "fail 4: $invokeOrder != 0_1_9 or $result != $expectedResult" + + return "OK" +} + +fun Double.test(a: Int, b: Long, c: () -> String): String { + return { "${this}_${a}_${b}_${c()}"} () +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/argumentOrder/defaults.kt b/backend.native/tests/external/codegen/blackbox/argumentOrder/defaults.kt new file mode 100644 index 00000000000..7498df2eefc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/argumentOrder/defaults.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +var invokeOrder: String = "" + +fun test(x: Double = { invokeOrder += "x"; 1.0 }(), a: String, y: Long = { invokeOrder += "y"; 1 }(), b: String): String { + return "" + x + a + b + y; +} + +fun box(): String { + val funResult = test(b = { invokeOrder += "K"; "K" }(), a = { invokeOrder += "O"; "O" }()) + + if (invokeOrder != "KOxy" || funResult != "1.0OK1") return "fail: $invokeOrder != KOxy or $funResult != 1.0OK1" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/argumentOrder/extension.kt b/backend.native/tests/external/codegen/blackbox/argumentOrder/extension.kt new file mode 100644 index 00000000000..c95a3b491c1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/argumentOrder/extension.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + var invokeOrder = ""; + val expectedResult = "1.0_0_1_L" + val expectedInvokeOrder = "1_0_L" + var l = 1L + var i = 0 + + var result = 1.0.test(b = {invokeOrder += "1_"; l}(), a = {invokeOrder+="0_"; i}(), c = {invokeOrder += "L"; "L"}) + if (invokeOrder != expectedInvokeOrder || result != expectedResult) return "fail 1: $invokeOrder != $expectedInvokeOrder or $result != $expectedResult" + + invokeOrder = ""; + result = 1.0.test(b = {invokeOrder += "1_"; l}(), c = {invokeOrder += "L"; "L"}, a = {invokeOrder+="0_"; i}()) + if (invokeOrder != expectedInvokeOrder || result != expectedResult) return "fail 2: $invokeOrder != $expectedInvokeOrder or $result != $expectedResult" + + + invokeOrder = ""; + result = 1.0.test(c = {invokeOrder += "L"; "L"}, b = {invokeOrder += "1_"; l}(), a = {invokeOrder+="0_"; i}()) + if (invokeOrder != expectedInvokeOrder || result != expectedResult) return "fail 3: $invokeOrder != $expectedInvokeOrder or $result != $expectedResult" + + + invokeOrder = ""; + result = 1.0.test(a = {invokeOrder+="0_"; i}(), c = {invokeOrder += "L"; "L"}, b = {invokeOrder += "1_"; l}()) + if (invokeOrder != "0_1_L" || result != expectedResult) return "fail 4: $invokeOrder != 0_1_L or $result != $expectedResult" + + return "OK" +} + +fun Double.test(a: Int, b: Long, c: () -> String): String { + return "${this}_${a}_${b}_${c()}" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/argumentOrder/extensionInClass.kt b/backend.native/tests/external/codegen/blackbox/argumentOrder/extensionInClass.kt new file mode 100644 index 00000000000..01b3a736735 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/argumentOrder/extensionInClass.kt @@ -0,0 +1,40 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + return Z().test() +} + +class Z { + fun Double.test(a: Int, b: Long, c: () -> String): String { + return "${this}_${a}_${b}_${c()}" + } + + + fun test(): String { + var invokeOrder = ""; + val expectedResult = "1.0_0_1_L" + val expectedInvokeOrder = "1_0_L" + var l = 1L + var i = 0 + + var result = 1.0.test(b = { invokeOrder += "1_"; l }(), a = { invokeOrder += "0_"; i }(), c = { invokeOrder += "L"; "L" }) + if (invokeOrder != expectedInvokeOrder || result != expectedResult) return "fail 1: $invokeOrder != $expectedInvokeOrder or $result != $expectedResult" + + invokeOrder = ""; + result = 1.0.test(b = { invokeOrder += "1_"; l }(), c = { invokeOrder += "L"; "L" }, a = { invokeOrder += "0_"; i }()) + if (invokeOrder != expectedInvokeOrder || result != expectedResult) return "fail 2: $invokeOrder != $expectedInvokeOrder or $result != $expectedResult" + + + invokeOrder = ""; + result = 1.0.test(c = { invokeOrder += "L"; "L" }, b = { invokeOrder += "1_"; l }(), a = { invokeOrder += "0_"; i }()) + if (invokeOrder != expectedInvokeOrder || result != expectedResult) return "fail 3: $invokeOrder != $expectedInvokeOrder or $result != $expectedResult" + + + invokeOrder = ""; + result = 1.0.test(a = { invokeOrder += "0_"; i }(), c = { invokeOrder += "L"; "L" }, b = { invokeOrder += "1_"; l }()) + if (invokeOrder != "0_1_L" || result != expectedResult) return "fail 4: $invokeOrder != 0_1_L or $result != $expectedResult" + + return "OK" + } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/argumentOrder/kt9277.kt b/backend.native/tests/external/codegen/blackbox/argumentOrder/kt9277.kt new file mode 100644 index 00000000000..eb08fb7b719 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/argumentOrder/kt9277.kt @@ -0,0 +1,13 @@ +// KT-9277 Unexpected NullPointerException in an invocaton with named arguments + +fun box(): String { + foo(null) + + return "OK" +} + +fun foo(x : Int?){ + bar(z = x ?: return, y = x) +} + +fun bar(y : Int, z : Int) {} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/argumentOrder/lambdaMigration.kt b/backend.native/tests/external/codegen/blackbox/argumentOrder/lambdaMigration.kt new file mode 100644 index 00000000000..6ef53bff6ee --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/argumentOrder/lambdaMigration.kt @@ -0,0 +1,21 @@ +fun box(): String { + var res = ""; + var call = test(a = {res += "K"; "K"}(), b = {res+="O"; "O"}(), c = {res += "L"; "L"}) + if (res != "KOL" || call != "KOL") return "fail 1: $res != KOL or $call != KOL" + + res = ""; + call = test(a = {res += "K"; "K"}(), c = {res += "L"; "L"}, b = {res+="O"; "O"}()) + if (res != "KOL" || call != "KOL") return "fail 2: $res != KOL or $call != KOL" + + + res = ""; + call = test(c = {res += "L"; "L"}, a = {res += "K"; "K"}(), b = {res+="O"; "O"}()) + if (res != "KOL" || call != "KOL") return "fail 3: $res != KOL or $call != KOL" + + return "OK" + +} + +fun test(a: String, b: String, c: () -> String): String { + return a + b + c(); +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/argumentOrder/lambdaMigrationInClass.kt b/backend.native/tests/external/codegen/blackbox/argumentOrder/lambdaMigrationInClass.kt new file mode 100644 index 00000000000..7100b035e29 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/argumentOrder/lambdaMigrationInClass.kt @@ -0,0 +1,25 @@ +fun box(): String { + var res = ""; + var call = Z("Z").test(a = {res += "K"; "K"}(), b = {res+="O"; "O"}(), c = {res += "L"; "L"}) + if (res != "KOL" || call != "KOLZ") return "fail 1: $res != KOL or $call != KOLZ" + + res = ""; + call = Z("Z").test(a = {res += "K"; "K"}(), c = {res += "L"; "L"}, b = {res+="O"; "O"}()) + if (res != "KOL" || call != "KOLZ") return "fail 2: $res != KOL or $call != KOLZ" + + + res = ""; + call = Z("Z").test(c = {res += "L"; "L"}, a = {res += "K"; "K"}(), b = {res+="O"; "O"}()) + if (res != "KOL" || call != "KOLZ") return "fail 3: $res != KOL or $call != KOLZ" + + return "OK" + +} + +class Z(val p: String) { + + fun test(a: String, b: String, c: () -> String): String { + return a + b + c() + p; + } + +} diff --git a/backend.native/tests/external/codegen/blackbox/argumentOrder/simple.kt b/backend.native/tests/external/codegen/blackbox/argumentOrder/simple.kt new file mode 100644 index 00000000000..101a18974ca --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/argumentOrder/simple.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + var res = ""; + var call = test(b = {res += "K"; "K"}(), a = {res+="O"; "O"}(), c = {res += "L"; "L"}) + if (res != "KOL" || call != "OKL") return "fail 1: $res != KOL or $call != OKL" + + res = ""; + call = test(b = {res += "K"; "K"}(), c = {res += "L"; "L"}, a = {res+="O"; "O"}()) + if (res != "KOL" || call != "OKL") return "fail 2: $res != KOL or $call != OKL" + + + res = ""; + call = test(c = {res += "L"; "L"}, b = {res += "K"; "K"}(), a = {res+="O"; "O"}()) + if (res != "KOL" || call != "OKL") return "fail 3: $res != KOL or $call != OKL" + + return "OK" + +} + +fun test(a: String, b: String, c: () -> String): String { + return a + b + c(); +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/argumentOrder/simpleInClass.kt b/backend.native/tests/external/codegen/blackbox/argumentOrder/simpleInClass.kt new file mode 100644 index 00000000000..9bd916da6e0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/argumentOrder/simpleInClass.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + var res = ""; + var call = Z("Z").test(b = {res += "K"; "K"}(), a = {res+="O"; "O"}(), c = {res += "L"; "L"}) + if (res != "KOL" || call != "OKLZ") return "fail 1: $res != KOL or $call != OKLZ" + + res = ""; + call = Z("Z").test(b = {res += "K"; "K"}(), c = {res += "L"; "L"}, a = {res+="O"; "O"}()) + if (res != "KOL" || call != "OKLZ") return "fail 2: $res != KOL or $call != OKLZ" + + + res = ""; + call = Z("Z").test(c = {res += "L"; "L"}, b = {res += "K"; "K"}(), a = {res+="O"; "O"}()) + if (res != "KOL" || call != "OKLZ") return "fail 3: $res != KOL or $call != OKLZ" + + return "OK" + +} + +class Z(val p: String) { + fun test(a: String, b: String, c: () -> String): String { + return a + b + c() + p; + } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/arrayConstructorsSimple.kt b/backend.native/tests/external/codegen/blackbox/arrays/arrayConstructorsSimple.kt new file mode 100644 index 00000000000..bb2fd78e5f3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/arrayConstructorsSimple.kt @@ -0,0 +1,26 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun simpleIntArray(): Array = Array(3) { it } +fun simpleDoubleArray(): Array = Array(3) { it.toDouble() + 0.1 } +fun simpleStringArray(): Array = Array(3) { it.toString() } + +fun box(): String { + val ia = simpleIntArray() + assertEquals(0, ia[0]) + assertEquals(1, ia[1]) + assertEquals(2, ia[2]) + + val da = simpleDoubleArray() + assertEquals(0.1, da[0]) + assertEquals(1.1, da[1]) + assertEquals(2.1, da[2]) + + val sa = simpleStringArray() + assertEquals("0", sa[0]) + assertEquals("1", sa[1]) + assertEquals("2", sa[2]) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/arrayGetAssignMultiIndex.kt b/backend.native/tests/external/codegen/blackbox/arrays/arrayGetAssignMultiIndex.kt new file mode 100644 index 00000000000..5e8e8bbd546 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/arrayGetAssignMultiIndex.kt @@ -0,0 +1,11 @@ +operator fun Array.get(index1: Int, index2: Int) = this[index1 + index2] +operator fun Array.set(index1: Int, index2: Int, elem: String) { + this[index1 + index2] = elem +} + +fun box(): String { + val s = Array(1, { "" }) + s[1, -1] = "O" + s[2, -2] += "K" + return s[-3, 3] +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/arrayGetMultiIndex.kt b/backend.native/tests/external/codegen/blackbox/arrays/arrayGetMultiIndex.kt new file mode 100644 index 00000000000..6898a9b08e6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/arrayGetMultiIndex.kt @@ -0,0 +1,11 @@ +operator fun Array.get(index1: Int, index2: Int) = this[index1 + index2] +operator fun Array.set(index1: Int, index2: Int, elem: String) { + this[index1 + index2] = elem +} + +fun box(): String { + val s = Array(1, { "" }) + s[1, -1] = "OK" + return s[-2, 2] +} + diff --git a/backend.native/tests/external/codegen/blackbox/arrays/arrayInstanceOf.kt b/backend.native/tests/external/codegen/blackbox/arrays/arrayInstanceOf.kt new file mode 100644 index 00000000000..67206754e5a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/arrayInstanceOf.kt @@ -0,0 +1,29 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +//test [], get and iterator calls +fun test(createIntNotLong: Boolean): String { + val a = if (createIntNotLong) IntArray(5) else LongArray(5) + if (a is IntArray) { + val x = a.iterator() + var i = 0 + while (x.hasNext()) { + if (a[i] != x.next()) return "Fail $i" + i++ + } + return "O" + } else if (a is LongArray) { + val x = a.iterator() + var i = 0 + while (x.hasNext()) { + if (a.get(i) != x.next()) return "Fail $i" + i++ + } + return "K" + } + return "fail" +} + +fun box(): String { + return test(true) + test(false) +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/arrayPlusAssign.kt b/backend.native/tests/external/codegen/blackbox/arrays/arrayPlusAssign.kt new file mode 100644 index 00000000000..9a243990fd5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/arrayPlusAssign.kt @@ -0,0 +1,6 @@ +fun box(): String { + val s = IntArray(1) + s[0] = 5 + s[0] += 7 + return if (s[0] == 12) "OK" else "Fail ${s[0]}" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/arraysAreCloneable.kt b/backend.native/tests/external/codegen/blackbox/arrays/arraysAreCloneable.kt new file mode 100644 index 00000000000..f0860dadc0a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/arraysAreCloneable.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun foo(x: Cloneable) = x + +fun box(): String { + foo(arrayOf("")) + foo(intArrayOf()) + foo(longArrayOf()) + foo(shortArrayOf()) + foo(byteArrayOf()) + foo(charArrayOf()) + foo(doubleArrayOf()) + foo(floatArrayOf()) + foo(booleanArrayOf()) + + arrayOf("").clone() + intArrayOf().clone() + longArrayOf().clone() + shortArrayOf().clone() + byteArrayOf().clone() + charArrayOf().clone() + doubleArrayOf().clone() + floatArrayOf().clone() + booleanArrayOf().clone() + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/cloneArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/cloneArray.kt new file mode 100644 index 00000000000..fe7ae5ff309 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/cloneArray.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String { + val s = arrayOf("live", "long") + val t: Array = s.clone() + if (!(s contentEquals t)) return "Fail string" + if (s === t) return "Fail string identity" + + val ss = arrayOf(s, s) + val tt: Array> = ss.clone() + if (!(ss contentEquals tt)) return "Fail string[]" + if (ss === tt) return "Fail string[] identity" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/clonePrimitiveArrays.kt b/backend.native/tests/external/codegen/blackbox/arrays/clonePrimitiveArrays.kt new file mode 100644 index 00000000000..578c79c0d3c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/clonePrimitiveArrays.kt @@ -0,0 +1,40 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String { + val i = intArrayOf(1, 2) + if (!(i contentEquals i.clone())) return "Fail int" + if (i.clone() === i) return "Fail int identity" + + val j = longArrayOf(1L, 2L) + if (!(j contentEquals j.clone())) return "Fail long" + if (j.clone() === j) return "Fail long identity" + + val s = shortArrayOf(1.toShort(), 2.toShort()) + if (!(s contentEquals s.clone())) return "Fail short" + if (s.clone() === s) return "Fail short identity" + + val b = byteArrayOf(1.toByte(), 2.toByte()) + if (!(b contentEquals b.clone())) return "Fail byte" + if (b.clone() === b) return "Fail byte identity" + + val c = charArrayOf('a', 'b') + if (!(c contentEquals c.clone())) return "Fail char" + if (c.clone() === c) return "Fail char identity" + + val d = doubleArrayOf(1.0, -1.0) + if (!(d contentEquals d.clone())) return "Fail double" + if (d.clone() === d) return "Fail double identity" + + val f = floatArrayOf(1f, -1f) + if (!(f contentEquals f.clone())) return "Fail float" + if (f.clone() === f) return "Fail float identity" + + val z = booleanArrayOf(true, false) + if (!(z contentEquals z.clone())) return "Fail boolean" + if (z.clone() === z) return "Fail boolean identity" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/collectionAssignGetMultiIndex.kt b/backend.native/tests/external/codegen/blackbox/arrays/collectionAssignGetMultiIndex.kt new file mode 100644 index 00000000000..974b55f66a5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/collectionAssignGetMultiIndex.kt @@ -0,0 +1,12 @@ +operator fun ArrayList.get(index1: Int, index2: Int) = this[index1 + index2] +operator fun ArrayList.set(index1: Int, index2: Int, elem: String) { + this[index1 + index2] = elem +} + +fun box(): String { + val s = ArrayList(1) + s.add("") + s[1, -1] = "O" + s[2, -2] += "K" + return s[2, -2] +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/collectionGetMultiIndex.kt b/backend.native/tests/external/codegen/blackbox/arrays/collectionGetMultiIndex.kt new file mode 100644 index 00000000000..295f860f84a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/collectionGetMultiIndex.kt @@ -0,0 +1,11 @@ +operator fun ArrayList.get(index1: Int, index2: Int) = this[index1 + index2] +operator fun ArrayList.set(index1: Int, index2: Int, elem: String) { + this[index1 + index2] = elem +} + +fun box(): String { + val s = ArrayList(1) + s.add("") + s[1, -1] = "OK" + return s[2, -2] +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/forEachBooleanArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/forEachBooleanArray.kt new file mode 100644 index 00000000000..f0238410cc5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/forEachBooleanArray.kt @@ -0,0 +1,6 @@ +fun box(): String { + for (x in BooleanArray(5)) { + if (x != false) return "Fail $x" + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/forEachByteArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/forEachByteArray.kt new file mode 100644 index 00000000000..1ae8205531a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/forEachByteArray.kt @@ -0,0 +1,6 @@ +fun box(): String { + for (x in ByteArray(5)) { + if (x != 0.toByte()) return "Fail $x" + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/forEachCharArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/forEachCharArray.kt new file mode 100644 index 00000000000..4b797671175 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/forEachCharArray.kt @@ -0,0 +1,6 @@ +fun box(): String { + for (x in CharArray(5)) { + if (x != 0.toChar()) return "Fail $x" + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/forEachDoubleArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/forEachDoubleArray.kt new file mode 100644 index 00000000000..c1a79f222a3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/forEachDoubleArray.kt @@ -0,0 +1,6 @@ +fun box(): String { + for (x in DoubleArray(5)) { + if (x != 0.toDouble()) return "Fail $x" + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/forEachFloatArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/forEachFloatArray.kt new file mode 100644 index 00000000000..8245beab4ee --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/forEachFloatArray.kt @@ -0,0 +1,6 @@ +fun box(): String { + for (x in FloatArray(5)) { + if (x != 0.toFloat()) return "Fail $x" + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/forEachIntArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/forEachIntArray.kt new file mode 100644 index 00000000000..53ce12dd393 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/forEachIntArray.kt @@ -0,0 +1,6 @@ +fun box(): String { + for (x in IntArray(5)) { + if (x != 0) return "Fail $x" + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/forEachLongArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/forEachLongArray.kt new file mode 100644 index 00000000000..6ed0259f765 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/forEachLongArray.kt @@ -0,0 +1,6 @@ +fun box(): String { + for (x in LongArray(5)) { + if (x != 0.toLong()) return "Fail $x" + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/forEachShortArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/forEachShortArray.kt new file mode 100644 index 00000000000..a9145d42422 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/forEachShortArray.kt @@ -0,0 +1,6 @@ +fun box(): String { + for (x in ShortArray(5)) { + if (x != 0.toShort()) return "Fail $x" + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/hashMap.kt b/backend.native/tests/external/codegen/blackbox/arrays/hashMap.kt new file mode 100644 index 00000000000..9c04d4911d6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/hashMap.kt @@ -0,0 +1,9 @@ +operator fun HashMap.set(index: String, elem: Int?) { + this.put(index, elem) +} + +fun box(): String { + val s = HashMap() + s["239"] = 239 + return if (s["239"] == 239) "OK" else "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/inProjectionAsParameter.kt b/backend.native/tests/external/codegen/blackbox/arrays/inProjectionAsParameter.kt new file mode 100644 index 00000000000..d89fdf1f02b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/inProjectionAsParameter.kt @@ -0,0 +1,9 @@ +fun test(y: Array>) { + y[0] = kotlin.arrayOf("OK") +} + +fun box() : String { + val x : Array> = kotlin.arrayOf(kotlin.arrayOf(1)) + test(x) + return x[0][0] as String +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/inProjectionOfArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/inProjectionOfArray.kt new file mode 100644 index 00000000000..87785a47aaf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/inProjectionOfArray.kt @@ -0,0 +1,10 @@ +fun box(): String { + val x : Array> = arrayOf(arrayOf(1)) + val y : Array> = x + + if (y.size != 1) return "fail 1" + + y[0] = arrayOf("OK") + + return x[0][0] as String +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/inProjectionOfList.kt b/backend.native/tests/external/codegen/blackbox/arrays/inProjectionOfList.kt new file mode 100644 index 00000000000..3a22c9124c9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/inProjectionOfList.kt @@ -0,0 +1,12 @@ +// WITH_RUNTIME + +fun box(): String { + val x: Array> = arrayOf(listOf(1)) + val y : Array> = x + + if (y.size != 1) return "fail 1" + + y[0] = listOf("OK") + + return x[0][0] as String +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/indices.kt b/backend.native/tests/external/codegen/blackbox/arrays/indices.kt new file mode 100644 index 00000000000..65976591a77 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/indices.kt @@ -0,0 +1,11 @@ +// WITH_RUNTIME + +fun box(): String { + val a = Array(5, {it}) + val x = a.indices.iterator() + while (x.hasNext()) { + val i = x.next() + if (a[i] != i) return "Fail $i ${a[i]}" + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/indicesChar.kt b/backend.native/tests/external/codegen/blackbox/arrays/indicesChar.kt new file mode 100644 index 00000000000..5d3470e389d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/indicesChar.kt @@ -0,0 +1,11 @@ +// WITH_RUNTIME + +fun box(): String { + val a = CharArray(5) + val x = a.indices.iterator() + while (x.hasNext()) { + val i = x.next() + if (a[i] != 0.toChar()) return "Fail $i ${a[i]}" + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/iterator.kt b/backend.native/tests/external/codegen/blackbox/arrays/iterator.kt new file mode 100644 index 00000000000..eb8f84cbb04 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/iterator.kt @@ -0,0 +1,9 @@ +fun box(): String { + val x = Array(5, { it } ).iterator() + var i = 0 + while (x.hasNext()) { + if (x.next() != i) return "Fail $i" + i++ + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/iteratorBooleanArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/iteratorBooleanArray.kt new file mode 100644 index 00000000000..753381f34f4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/iteratorBooleanArray.kt @@ -0,0 +1,10 @@ +fun box(): String { + val a = BooleanArray(5) + val x = a.iterator() + var i = 0 + while (x.hasNext()) { + if (a[i] != x.next()) return "Fail $i" + i++ + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/iteratorByteArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/iteratorByteArray.kt new file mode 100644 index 00000000000..259eb5f3200 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/iteratorByteArray.kt @@ -0,0 +1,10 @@ +fun box(): String { + val a = ByteArray(5) + val x = a.iterator() + var i = 0 + while (x.hasNext()) { + if (a[i] != x.next()) return "Fail $i" + i++ + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/iteratorByteArrayNextByte.kt b/backend.native/tests/external/codegen/blackbox/arrays/iteratorByteArrayNextByte.kt new file mode 100644 index 00000000000..4970504900c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/iteratorByteArrayNextByte.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + val a = ByteArray(5) + val x = a.iterator() + var i = 0 + while (x.hasNext()) { + if (a[i] != x.nextByte()) return "Fail $i" + i++ + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/iteratorCharArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/iteratorCharArray.kt new file mode 100644 index 00000000000..525910d31e3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/iteratorCharArray.kt @@ -0,0 +1,10 @@ +fun box(): String { + val a = CharArray(5) + val x = a.iterator() + var i = 0 + while (x.hasNext()) { + if (a[i] != x.next()) return "Fail $i" + i++ + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/iteratorDoubleArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/iteratorDoubleArray.kt new file mode 100644 index 00000000000..192625f22c6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/iteratorDoubleArray.kt @@ -0,0 +1,10 @@ +fun box(): String { + val a = DoubleArray(5) + val x = a.iterator() + var i = 0 + while (x.hasNext()) { + if (a[i] != x.next()) return "Fail $i" + i++ + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/iteratorFloatArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/iteratorFloatArray.kt new file mode 100644 index 00000000000..4a5b86e694f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/iteratorFloatArray.kt @@ -0,0 +1,10 @@ +fun box(): String { + val a = FloatArray(5) + val x = a.iterator() + var i = 0 + while (x.hasNext()) { + if (a[i] != x.next()) return "Fail $i" + i++ + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/iteratorIntArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/iteratorIntArray.kt new file mode 100644 index 00000000000..2dd09e3a59c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/iteratorIntArray.kt @@ -0,0 +1,10 @@ +fun box(): String { + val a = IntArray(5) + val x = a.iterator() + var i = 0 + while (x.hasNext()) { + if (a[i] != x.next()) return "Fail $i" + i++ + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/iteratorLongArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/iteratorLongArray.kt new file mode 100644 index 00000000000..b1033002764 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/iteratorLongArray.kt @@ -0,0 +1,10 @@ +fun box(): String { + val a = LongArray(5) + val x = a.iterator() + var i = 0 + while (x.hasNext()) { + if (a[i] != x.next()) return "Fail $i" + i++ + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/iteratorLongArrayNextLong.kt b/backend.native/tests/external/codegen/blackbox/arrays/iteratorLongArrayNextLong.kt new file mode 100644 index 00000000000..ef44f5426d0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/iteratorLongArrayNextLong.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + val a = LongArray(5) + val x = a.iterator() + var i = 0 + while (x.hasNext()) { + if (a[i] != x.nextLong()) return "Fail $i" + i++ + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/iteratorShortArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/iteratorShortArray.kt new file mode 100644 index 00000000000..49807e23720 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/iteratorShortArray.kt @@ -0,0 +1,10 @@ +fun box(): String { + val a = ShortArray(5) + val x = a.iterator() + var i = 0 + while (x.hasNext()) { + if (a[i] != x.next()) return "Fail $i" + i++ + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/kt1291.kt b/backend.native/tests/external/codegen/blackbox/arrays/kt1291.kt new file mode 100644 index 00000000000..02b5fd89707 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/kt1291.kt @@ -0,0 +1,27 @@ +var result = 0 + +fun Iterator.foreach(action: (T) -> Unit) { + while (this.hasNext()) { + (action)(this.next()) + } +} + +fun Iterator.select(f: (In) -> Out) : Iterator { + return Selector(this, f); +} + +class Selector(val source: Iterator, val f: (In) -> Out) : Iterator { + override fun hasNext(): Boolean = source.hasNext() + + override fun next(): Out { + return (f)(source.next()) + } +} + +fun box(): String { + Array(4, { it + 1 }).iterator() + .select({i -> i * 10}) + .foreach({k -> result += k}) + if (result != 10+20+30+40) return "Fail: $result" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/kt238.kt b/backend.native/tests/external/codegen/blackbox/arrays/kt238.kt new file mode 100644 index 00000000000..71c935d5c9d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/kt238.kt @@ -0,0 +1,58 @@ +fun t1 () { + val a1 = arrayOfNulls(1) + a1[0] = "0" //ok + val s = a1[0] //ok +} + +fun t2 () { + val a2 = arrayOfNulls(1) as Array + a2[0] = 0 //ok + var i = a2[0] //ok +} + +fun t3 () { + val a3 = arrayOfNulls(1) + a3[0] = 0 //verify error + var j = a3[0] //ok + var k : Int = a3[0] ?: 5 //ok +} + +fun t4 () { + val b1 = StrangeIntArray(10) + b1[4] = 5 //ok + var i = b1[1] //ok +} + +fun t5 () { + val b2 = StrangeArray(10, 0) + b2.set(4, 5) //ok + b2[4] = 5 //verify error + var i = b2.get(2) //ok + i = b2[1] //verify error +} + +fun t6() { + val b3 = StrangeArray(10, 0) + b3.set(5, 6) //ok + b3[4] = 5 //verify error + val v = b3[1] //ok +} + +fun box() : String { + return "OK" +} + +class StrangeArray(size: Int, private var defaultValue: T) { + operator fun get(index: Int): T = defaultValue + operator fun set(index: Int, v: T) { + defaultValue = v + } +} + +class StrangeIntArray(size: Int) { + private var defaultValue = 0 + operator fun get(index: Int): Int = defaultValue + operator fun set(index: Int, v: Int) { + defaultValue = v + } +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/kt2997.kt b/backend.native/tests/external/codegen/blackbox/arrays/kt2997.kt new file mode 100644 index 00000000000..f42acc4a2e9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/kt2997.kt @@ -0,0 +1,77 @@ +//KT-2997 Automatically cast error (Array) + +fun foo(a: Any): Int { + if (a is IntArray) { + a.get(0) + a.set(0, 1) + a.iterator() + return a.size + } + if (a is ShortArray) { + a.get(0) + a.set(0, 1) + a.iterator() + return a.size + } + if (a is ByteArray) { + a.get(0) + a.set(0, 1) + a.iterator() + return a.size + } + if (a is FloatArray) { + a.get(0) + a.set(0, 1.toFloat()) + a.iterator() + return a.size + } + if (a is DoubleArray) { + a.get(0) + a.set(0, 1.0) + a.iterator() + return a.size + } + if (a is BooleanArray) { + a.get(0) + a.set(0, false) + a.iterator() + return a.size + } + if (a is CharArray) { + a.get(0) + a.set(0, 'a') + a.iterator() + return a.size + } + if (a is Array<*>) { + if (a.size > 0) a.get(0) + a.iterator() + return a.size + } + + return 0 +} + +fun box(): String { + val iA = IntArray(1) + if (foo(iA) != 1) return "fail int[]" + val sA = ShortArray(1) + if (foo(sA) != 1) return "fail short[]" + val bA = ByteArray(1) + if (foo(bA) != 1) return "fail byte[]" + val fA = FloatArray(1) + if (foo(fA) != 1) return "fail float[]" + val dA = DoubleArray(1) + if (foo(dA) != 1) return "fail double[]" + val boolA = BooleanArray(1) + if (foo(boolA) != 1) return "fail boolean[]" + val cA = CharArray(1) + if (foo(cA) != 1) return "fail char[]" + val oA = arrayOfNulls(1) + if (foo(oA) != 1) return "fail Any[]" + + val sArray = arrayOfNulls(0) + if (foo(sArray) != 0) return "fail String[]" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/kt33.kt b/backend.native/tests/external/codegen/blackbox/arrays/kt33.kt new file mode 100644 index 00000000000..25941e0f5cd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/kt33.kt @@ -0,0 +1,6 @@ +fun box () : String { + val s = ArrayList() + s.add("foo") + s[0] += "bar" + return if(s[0] == "foobar") "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/kt3771.kt b/backend.native/tests/external/codegen/blackbox/arrays/kt3771.kt new file mode 100644 index 00000000000..60db734b833 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/kt3771.kt @@ -0,0 +1,14 @@ +fun fill(dest : Array, v : String) { + dest[0] = v +} + +fun box() : String { +//fun main(args : Array) { + val s : String = "bar" + val any : Array = arrayOf(1, "foo", 1.234) + fill(any, s) + /* shouldn't throw +ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String; + */ + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/kt4118.kt b/backend.native/tests/external/codegen/blackbox/arrays/kt4118.kt new file mode 100644 index 00000000000..979effeed54 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/kt4118.kt @@ -0,0 +1,94 @@ +fun Array.test1(): Array { + val func = { i:Int -> this} + return func(1) +} + +fun Array.test1Nested(): Array { + val func = { i: Int -> { this }()} + return func(1) +} + + +fun Array.test2() : Array { + class Z2() { + fun run(): Array { + return this@test2 + } + } + return Z2().run() +} + +fun Array.test2Nested() : Array { + class Z2() { + fun run(): Array { + class Z3 { + fun run(): Array { + return this@test2Nested; + } + } + return Z3().run() + } + } + return Z2().run() +} + +fun Array.test3(): Array { + fun local(): Array { + return this@test3 + } + return local() +} + +fun Array.test3Nested(): Array { + fun local(): Array { + fun local2(): Array { + return this@test3Nested + } + return local2() + } + return local() +} + + +fun Array.test4() : Array { + return object { + fun run() : Array { + return this@test4 + } + }.run() +} + +fun Array.test4Nested() : Array { + return object { + fun run() : Array { + return object { + fun run() : Array { + return this@test4Nested + } + }.run() + } + }.run() +} + +fun Array.test1(): Array { + val func = { i: Int -> this} + return func(1) +} + + +fun box() : String { + val array = Array(2, { i -> "${i}" }) + if (array != array.test1()) return "fail 1" + if (array != array.test2()) return "fail 2" + if (array != array.test3()) return "fail 3" + if (array != array.test4()) return "fail 4" + + if (array != array.test1Nested()) return "fail 1Nested" + if (array != array.test2Nested()) return "fail 2Nested" + if (array != array.test3Nested()) return "fail 3Nested" + if (array != array.test4Nested()) return "fail 4Nested" + + val array2 = Array(2, { i -> DoubleArray(i) }) + if (array2 != array2.test1()) return "fail on array of double []" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/kt4348.kt b/backend.native/tests/external/codegen/blackbox/arrays/kt4348.kt new file mode 100644 index 00000000000..4ea639148ca --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/kt4348.kt @@ -0,0 +1,17 @@ +operator fun String.get(vararg value: Any) : String { + return if (value[0] == 44 && value[1] == "example") "OK" else "fail" +} + +operator fun Int.get(vararg value: Any) : Int { + return if (value[0] == 44 && value[1] == "example") 1 else 0 +} +fun main(args: Array) { + 12 [44, "example"] +} + +fun box(): String { + if ("foo" [44, "example"] != "OK") return "fail1" + if (11 [44, "example"] != 1) return "fail2" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/kt4357.kt b/backend.native/tests/external/codegen/blackbox/arrays/kt4357.kt new file mode 100644 index 00000000000..95b92765fa4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/kt4357.kt @@ -0,0 +1,8 @@ +fun box(): String { + val array = intArrayOf(11, 12, 13) + val p = array.get(0) + if (p != 11) return "fail 1: $p" + + val stringArray = arrayOf("OK", "FAIL") + return stringArray.get(0) +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/kt503.kt b/backend.native/tests/external/codegen/blackbox/arrays/kt503.kt new file mode 100644 index 00000000000..d42e3e112a3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/kt503.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun iarr(vararg a : Int) = a +fun array(vararg a : T) = a + +fun box() : String { + val tests = array( + iarr(6, 5, 4, 3, 2, 1), + iarr(1, 2), + iarr(1, 2, 3), + iarr(1, 2, 3, 4), + iarr(1) + ) + + var n = 0 + + try { + var i = 0 + while (true) { + if (thirdElementIsThree(tests[i++])) + n++ + } + } + catch (e : ArrayIndexOutOfBoundsException) { + // No more tests to process + } + return if(n == 2) "OK" else "fail" +} + +fun thirdElementIsThree(a : IntArray) = + a.size >= 3 && a[2] == 3 diff --git a/backend.native/tests/external/codegen/blackbox/arrays/kt594.kt b/backend.native/tests/external/codegen/blackbox/arrays/kt594.kt new file mode 100644 index 00000000000..c67bd1b66e7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/kt594.kt @@ -0,0 +1,16 @@ +package array_test + +fun box() : String { + var array : IntArray? = IntArray(10) + array?.set(0, 3) + if(array?.get(0) != 3) return "fail" + + var a = arrayOfNulls>(5) + var b = arrayOfNulls(1) + b.set(0, "239") + a?.set(0, b) + + if(a?.get(0)?.get(0) != "239") return "fail" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/kt602.kt b/backend.native/tests/external/codegen/blackbox/arrays/kt602.kt new file mode 100644 index 00000000000..471a56cc117 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/kt602.kt @@ -0,0 +1,6 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box() = if(arrayOfNulls(10).isArrayOf()) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/arrays/kt7009.kt b/backend.native/tests/external/codegen/blackbox/arrays/kt7009.kt new file mode 100644 index 00000000000..91cf7e4fa5b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/kt7009.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME + +fun box() : String { + val value = (1 to doubleArrayOf(1.0)).second[0] + return if (value == 1.0) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/kt7288.kt b/backend.native/tests/external/codegen/blackbox/arrays/kt7288.kt new file mode 100644 index 00000000000..80060cd39f8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/kt7288.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun test(b: Boolean): String { + val a = if (b) IntArray(5) else LongArray(5) + if (a is IntArray) { + val x = a.iterator() + var i = 0 + while (x.hasNext()) { + if (a[i] != x.next()) return "Fail $i" + i++ + } + return "OK" + } else if (a is LongArray) { + val x = a.iterator() + var i = 0 + while (x.hasNext()) { + if (a[i] != x.next()) return "Fail $i" + i++ + } + return "OK" + } + return "fail" +} + +fun box(): String { + if (test(true) != "OK") return "fail 1: ${test(true)}" + + if (test(false) != "OK") return "fail 1: ${test(false)}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/kt7338.kt b/backend.native/tests/external/codegen/blackbox/arrays/kt7338.kt new file mode 100644 index 00000000000..848764b3f57 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/kt7338.kt @@ -0,0 +1,12 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun foo(x : Any): String { + return if(x is Array<*> && x.isArrayOf()) (x as Array)[0] else "fail" +} + +fun box(): String { + return foo(arrayOf("OK")) +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/kt779.kt b/backend.native/tests/external/codegen/blackbox/arrays/kt779.kt new file mode 100644 index 00000000000..a56d1e0874b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/kt779.kt @@ -0,0 +1,3 @@ +val Array.length : Int get() = this.size + +fun box() = if(arrayOfNulls(10).length == 10) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/arrays/kt945.kt b/backend.native/tests/external/codegen/blackbox/arrays/kt945.kt new file mode 100644 index 00000000000..eaf6c5e61b6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/kt945.kt @@ -0,0 +1,9 @@ +fun box() : String { + val data = Array>(3) { Array(4, {false}) } + for(d in data) { + if(d.size != 4) return "fail" + for(b in d) if (b) return "fail" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/kt950.kt b/backend.native/tests/external/codegen/blackbox/arrays/kt950.kt new file mode 100644 index 00000000000..f9d26d44d43 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/kt950.kt @@ -0,0 +1,7 @@ +operator fun MutableMap.set(k : K, v : V) = put(k, v) + +fun box() : String { + val map = HashMap() + map["239"] = "932" + return if(map["239"] == "932") "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/longAsIndex.kt b/backend.native/tests/external/codegen/blackbox/arrays/longAsIndex.kt new file mode 100644 index 00000000000..c12d4dca9a4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/longAsIndex.kt @@ -0,0 +1,9 @@ +operator fun IntArray.set(index: Long, elem: Int) { this[index.toInt()] = elem } +operator fun IntArray.get(index: Long) = this[index.toInt()] + +fun box(): String { + var l = IntArray(1) + l[0.toLong()] = 4 + l[0.toLong()] += 6 + return if (l[0.toLong()] == 10) "OK" else "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/multiArrayConstructors.kt b/backend.native/tests/external/codegen/blackbox/arrays/multiArrayConstructors.kt new file mode 100644 index 00000000000..77663265456 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/multiArrayConstructors.kt @@ -0,0 +1,31 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun stringMultiArray(): Array> = Array(3) { + i -> Array(3) { j -> "$i-$j" } +} + +fun stringNullableMultiArray(): Array> = Array(3) { + i -> if (i == 1) Array(3) { j -> "$i-$j" } as Array else arrayOfNulls(3) +} + +fun box(): String { + val matrix = stringMultiArray() + + for (i in 0..2) { + for (j in 0..2) { + assertEquals("$i-$j", matrix[i][j], "matrix") + } + } + + val matrixNullable = stringNullableMultiArray() + + for (j in 0..2) { + assertEquals(null, matrixNullable[0][j], "nullable") + assertEquals("1-$j", matrixNullable[1][j], "nullable") + assertEquals(null, matrixNullable[2][j], "nullable") + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/MultiDeclFor.kt b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/MultiDeclFor.kt new file mode 100644 index 00000000000..8657604547a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/MultiDeclFor.kt @@ -0,0 +1,18 @@ +class C(val i: Int) { + operator fun component1() = i + 1 + operator fun component2() = i + 2 +} + +fun doTest(l : Array): String { + var s = "" + for ((a, b) in l) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val l = Array(3, {x -> C(x)}) + val s = doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/MultiDeclForComponentExtensions.kt b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/MultiDeclForComponentExtensions.kt new file mode 100644 index 00000000000..056a9f5f793 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/MultiDeclForComponentExtensions.kt @@ -0,0 +1,19 @@ +class C(val i: Int) { +} + +operator fun C.component1() = i + 1 +operator fun C.component2() = i + 2 + +fun doTest(l : Array): String { + var s = "" + for ((a, b) in l) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val l = Array(3, {x -> C(x)}) + val s = doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/MultiDeclForComponentMemberExtensions.kt b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/MultiDeclForComponentMemberExtensions.kt new file mode 100644 index 00000000000..6a9f6be2409 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/MultiDeclForComponentMemberExtensions.kt @@ -0,0 +1,21 @@ +class C(val i: Int) { +} + +class M { + operator fun C.component1() = i + 1 + operator fun C.component2() = i + 2 + + fun doTest(l : Array): String { + var s = "" + for ((a, b) in l) { + s += "$a:$b;" + } + return s + } +} + +fun box(): String { + val l = Array(3, {x -> C(x)}) + val s = M().doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt new file mode 100644 index 00000000000..376aabb2466 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt @@ -0,0 +1,21 @@ +class C(val i: Int) { +} + +class M { + operator fun C.component1() = i + 1 + operator fun C.component2() = i + 2 +} + +fun M.doTest(l : Array): String { + var s = "" + for ((a, b) in l) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val l = Array(3, {x -> C(x)}) + val s = M().doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/MultiDeclForValCaptured.kt b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/MultiDeclForValCaptured.kt new file mode 100644 index 00000000000..f25b504d607 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/MultiDeclForValCaptured.kt @@ -0,0 +1,18 @@ +class C(val i: Int) { + operator fun component1() = i + 1 + operator fun component2() = i + 2 +} + +fun doTest(l : Array): String { + var s = "" + for ((a, b) in l) { + s += {"$a:$b;"}() + } + return s +} + +fun box(): String { + val l = Array(3, {x -> C(x)}) + val s = doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/int/MultiDeclForComponentExtensions.kt b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/int/MultiDeclForComponentExtensions.kt new file mode 100644 index 00000000000..f0687781516 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/int/MultiDeclForComponentExtensions.kt @@ -0,0 +1,16 @@ +operator fun Int.component1() = this + 1 +operator fun Int.component2() = this + 2 + +fun doTest(l : Array): String { + var s = "" + for ((a, b) in l) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val l = Array(3, {x -> x}) + val s = doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/int/MultiDeclForComponentExtensionsValCaptured.kt b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/int/MultiDeclForComponentExtensionsValCaptured.kt new file mode 100644 index 00000000000..3dda25067f3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/int/MultiDeclForComponentExtensionsValCaptured.kt @@ -0,0 +1,16 @@ +operator fun Int.component1() = this + 1 +operator fun Int.component2() = this + 2 + +fun doTest(l : Array): String { + var s = "" + for ((a, b) in l) { + s += {"$a:$b;"}() + } + return s +} + +fun box(): String { + val l = Array(3, {x -> x}) + val s = doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/int/MultiDeclForComponentMemberExtensions.kt b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/int/MultiDeclForComponentMemberExtensions.kt new file mode 100644 index 00000000000..2cf40134bf3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/int/MultiDeclForComponentMemberExtensions.kt @@ -0,0 +1,18 @@ +class M { + operator fun Int.component1() = this + 1 + operator fun Int.component2() = this + 2 + + fun doTest(l : Array): String { + var s = "" + for ((a, b) in l) { + s += "$a:$b;" + } + return s + } +} + +fun box(): String { + val l = Array(3, {x -> x}) + val s = M().doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/int/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/int/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt new file mode 100644 index 00000000000..9ad2af28556 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/int/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt @@ -0,0 +1,18 @@ +class M { + operator fun Int.component1() = this + 1 + operator fun Int.component2() = this + 2 +} + +fun M.doTest(l : Array): String { + var s = "" + for ((a, b) in l) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val l = Array(3, {x -> x}) + val s = M().doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/long/MultiDeclForComponentExtensions.kt b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/long/MultiDeclForComponentExtensions.kt new file mode 100644 index 00000000000..0ca7fc49d13 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/long/MultiDeclForComponentExtensions.kt @@ -0,0 +1,16 @@ +operator fun Long.component1() = this + 1 +operator fun Long.component2() = this + 2 + +fun doTest(l : Array): String { + var s = "" + for ((a, b) in l) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val l = Array(3, {x -> x.toLong()}) + val s = doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/long/MultiDeclForComponentExtensionsValCaptured.kt b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/long/MultiDeclForComponentExtensionsValCaptured.kt new file mode 100644 index 00000000000..3e610b49997 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/long/MultiDeclForComponentExtensionsValCaptured.kt @@ -0,0 +1,16 @@ +operator fun Long.component1() = this + 1 +operator fun Long.component2() = this + 2 + +fun doTest(l : Array): String { + var s = "" + for ((a, b) in l) { + s += {"$a:$b;"}() + } + return s +} + +fun box(): String { + val l = Array(3, {x -> x.toLong()}) + val s = doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/long/MultiDeclForComponentMemberExtensions.kt b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/long/MultiDeclForComponentMemberExtensions.kt new file mode 100644 index 00000000000..dad12c6d80f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/long/MultiDeclForComponentMemberExtensions.kt @@ -0,0 +1,18 @@ +class M { + operator fun Long.component1() = this + 1 + operator fun Long.component2() = this + 2 + + fun doTest(l : Array): String { + var s = "" + for ((a, b) in l) { + s += "$a:$b;" + } + return s + } +} + +fun box(): String { + val l = Array(3, {x -> x.toLong()}) + val s = M().doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/long/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/long/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt new file mode 100644 index 00000000000..fde531f8d21 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/multiDecl/long/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt @@ -0,0 +1,18 @@ +class M { + operator fun Long.component1() = this + 1 + operator fun Long.component2() = this + 2 +} + +fun M.doTest(l : Array): String { + var s = "" + for ((a, b) in l) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val l = Array(3, {x -> x.toLong()}) + val s = M().doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/arrays/nonLocalReturnArrayConstructor.kt b/backend.native/tests/external/codegen/blackbox/arrays/nonLocalReturnArrayConstructor.kt new file mode 100644 index 00000000000..6c9158aa1a5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/nonLocalReturnArrayConstructor.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun testArray() { + Array(5) { i -> + if (i == 3) return + i.toString() + } + throw AssertionError() +} + +fun testIntArray() { + IntArray(5) { i -> + if (i == 3) return + i + } + throw AssertionError() +} + +fun box(): String { + testArray() + testIntArray() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/arrays/nonNullArray.kt b/backend.native/tests/external/codegen/blackbox/arrays/nonNullArray.kt new file mode 100644 index 00000000000..2e480979e6b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/nonNullArray.kt @@ -0,0 +1,8 @@ +class A() { + class B(val i: Int) { + } + + fun test() = Array (10, { B(it) }) +} + +fun box() = if(A().test()[5].i == 5) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/arrays/stdlib.kt b/backend.native/tests/external/codegen/blackbox/arrays/stdlib.kt new file mode 100644 index 00000000000..41f1090eba1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/arrays/stdlib.kt @@ -0,0 +1,56 @@ +interface ISized { + val size : Int +} + +interface javaUtilIterator : Iterator { + fun remove() : Unit { + throw UnsupportedOperationException() + } +} + +class MyIterator(val array : ReadOnlyArray) : javaUtilIterator { + private var index = 0 + + override fun hasNext() : Boolean = index < array.size + + override fun next() : T = array.get(index++) +} + +interface ReadOnlyArray : ISized, Iterable { + operator fun get(index : Int) : T + + override fun iterator() : Iterator = MyIterator(this) +} + +interface WriteOnlyArray : ISized { + operator fun set(index : Int, value : T) : Unit + + operator fun set(from: Int, count: Int, value: T) { + for(i in from..from+count-1) { + set(i, value) + } + } +} + +class MutableArray(length: Int, init : (Int) -> T) : ReadOnlyArray, WriteOnlyArray { + private val array = Array(length, init) + + override fun get(index : Int) : T = array[index] as T + override fun set(index : Int, value : T) : Unit { array[index] = value } + + override val size : Int + get() = array.size +} + +fun box() : String { + var a = MutableArray (4, {0}) + a [0] = 10 + a.set(1, 2, 13) + a [3] = 40 + a.iterator() + a.iterator().hasNext() + for(el in a) { + val fl = el + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/binaryOp/bitwiseOp.kt b/backend.native/tests/external/codegen/blackbox/binaryOp/bitwiseOp.kt new file mode 100644 index 00000000000..7618481db4c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/binaryOp/bitwiseOp.kt @@ -0,0 +1,67 @@ +fun box(): String { + // D = 1101 C = 1100 + // 6 = 0110 5 = 0101 + var iarg1: Int = 0xDC56DC56.toInt() + var iarg2: Int = 0x65DC65DC + var i1 = iarg1 and iarg2 + var i2 = iarg1 or iarg2 + var i3 = iarg1 xor iarg2 + var i4 = iarg1.inv() + var i5 = iarg1 shl 16 + var i6 = iarg1 shr 16 + var i7 = iarg1 ushr 16 + + if (i1 != 0x44544454.toInt()) return "fail: Int.and" + if (i2 != 0xFDDEFDDE.toInt()) return "fail: Int.or" + if (i3 != 0xB98AB98A.toInt()) return "fail: Int.xor" + if (i4 != 0x23A923A9.toInt()) return "fail: Int.inv" + if (i5 != 0xDC560000.toInt()) return "fail: Int.shl" + if (i6 != 0xFFFFDC56.toInt()) return "fail: Int.shr" + if (i7 != 0x0000DC56.toInt()) return "fail: Int.ushr" + + + // TODO: Use long hex constants after KT-4749 is fixed + var larg1: Long = (0xDC56DC56L shl 32) + 0xDC56DC56 // !!!! + var larg2: Long = 0x65DC65DC65DC65DC + var l1 = larg1 and larg2 + var l2 = larg1 or larg2 + var l3 = larg1 xor larg2 + var l4 = larg1.inv() + var l5 = larg1 shl 32 + var l6 = larg1 shr 32 + var l7 = larg1 ushr 32 + + if (l1 != 0x4454445444544454) return "fail: Long.and" + if (l2 != (0xFDDEFDDEL shl 32) + 0xFDDEFDDE) return "fail: Long.or" + if (l3 != (0xB98AB98AL shl 32) + 0xB98AB98A) return "fail: Long.xor" + if (l4 != 0x23A923A923A923A9) return "fail: Long.inv" + if (l5 != (0xDC56DC56L shl 32)/*!!!*/) return "fail: Long.shl" + if (l6 != (0xFFFFFFFFL shl 32) + 0xDC56DC56) return "fail: Long.shr" + if (l7 != (0x00000000L shl 32) + 0xDC56DC56.toLong()) return "fail: Long.ushr" + + var sarg1: Short = 0xDC56.toShort() + var sarg2: Short = 0x65DC.toShort() + var s1 = sarg1 and sarg2 + var s2 = sarg1 or sarg2 + var s3 = sarg1 xor sarg2 + var s4 = sarg1.inv() + + if (s1 != 0x4454.toShort()) return "fail: Short.and" + if (s2 != 0xFDDE.toShort()) return "fail: Short.or" + if (s3 != 0xB98A.toShort()) return "fail: Short.xor" + if (s4 != 0x23A9.toShort()) return "fail: Short.inv" + + var barg1: Byte = 0xDC.toByte() + var barg2: Byte = 0x65.toByte() + var b1 = barg1 and barg2 + var b2 = barg1 or barg2 + var b3 = barg1 xor barg2 + var b4 = barg1.inv() + + if (b1 != 0x44.toByte()) return "fail: Byte.and" + if (b2 != 0xFD.toByte()) return "fail: Byte.or" + if (b3 != 0xB9.toByte()) return "fail: Byte.xor" + if (b4 != 0x23.toByte()) return "fail: Byte.inv" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/binaryOp/bitwiseOpAny.kt b/backend.native/tests/external/codegen/blackbox/binaryOp/bitwiseOpAny.kt new file mode 100644 index 00000000000..035248d5adb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/binaryOp/bitwiseOpAny.kt @@ -0,0 +1,67 @@ +fun box(): String { + // D = 1101 C = 1100 + // 6 = 0110 5 = 0101 + var iarg1: Int = 0xDC56DC56.toInt() + var iarg2: Int = 0x65DC65DC + var i1: Any = iarg1 and iarg2 + var i2: Any = iarg1 or iarg2 + var i3: Any = iarg1 xor iarg2 + var i4: Any = iarg1.inv() + var i5: Any = iarg1 shl 16 + var i6: Any = iarg1 shr 16 + var i7: Any = iarg1 ushr 16 + + if (i1 != 0x44544454.toInt()) return "fail: Int.and" + if (i2 != 0xFDDEFDDE.toInt()) return "fail: Int.or" + if (i3 != 0xB98AB98A.toInt()) return "fail: Int.xor" + if (i4 != 0x23A923A9.toInt()) return "fail: Int.inv" + if (i5 != 0xDC560000.toInt()) return "fail: Int.shl" + if (i6 != 0xFFFFDC56.toInt()) return "fail: Int.shr" + if (i7 != 0x0000DC56.toInt()) return "fail: Int.ushr" + + + // TODO: Use long hex constants after KT-4749 is fixed + var larg1: Long = (0xDC56DC56L shl 32) + 0xDC56DC56 // !!!! + var larg2: Long = 0x65DC65DC65DC65DC + var l1: Any = larg1 and larg2 + var l2: Any = larg1 or larg2 + var l3: Any = larg1 xor larg2 + var l4: Any = larg1.inv() + var l5: Any = larg1 shl 32 + var l6: Any = larg1 shr 32 + var l7: Any = larg1 ushr 32 + + if (l1 != 0x4454445444544454) return "fail: Long.and" + if (l2 != (0xFDDEFDDEL shl 32) + 0xFDDEFDDE) return "fail: Long.or" + if (l3 != (0xB98AB98AL shl 32) + 0xB98AB98A) return "fail: Long.xor" + if (l4 != 0x23A923A923A923A9) return "fail: Long.inv" + if (l5 != (0xDC56DC56L shl 32)/*!!!*/) return "fail: Long.shl" + if (l6 != (0xFFFFFFFFL shl 32) + 0xDC56DC56) return "fail: Long.shr" + if (l7 != (0x00000000L shl 32) + 0xDC56DC56.toLong()) return "fail: Long.ushr" + + var sarg1: Short = 0xDC56.toShort() + var sarg2: Short = 0x65DC.toShort() + var s1: Any = sarg1 and sarg2 + var s2: Any = sarg1 or sarg2 + var s3: Any = sarg1 xor sarg2 + var s4: Any = sarg1.inv() + + if (s1 != 0x4454.toShort()) return "fail: Short.and" + if (s2 != 0xFDDE.toShort()) return "fail: Short.or" + if (s3 != 0xB98A.toShort()) return "fail: Short.xor" + if (s4 != 0x23A9.toShort()) return "fail: Short.inv" + + var barg1: Byte = 0xDC.toByte() + var barg2: Byte = 0x65.toByte() + var b1: Any = barg1 and barg2 + var b2: Any = barg1 or barg2 + var b3: Any = barg1 xor barg2 + var b4: Any = barg1.inv() + + if (b1 != 0x44.toByte()) return "fail: Byte.and" + if (b2 != 0xFD.toByte()) return "fail: Byte.or" + if (b3 != 0xB9.toByte()) return "fail: Byte.xor" + if (b4 != 0x23.toByte()) return "fail: Byte.inv" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/binaryOp/bitwiseOpNullable.kt b/backend.native/tests/external/codegen/blackbox/binaryOp/bitwiseOpNullable.kt new file mode 100644 index 00000000000..779f86f9315 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/binaryOp/bitwiseOpNullable.kt @@ -0,0 +1,67 @@ +fun box(): String { + // D = 1101 C = 1100 + // 6 = 0110 5 = 0101 + var iarg1: Int = 0xDC56DC56.toInt() + var iarg2: Int = 0x65DC65DC + var i1: Int? = iarg1 and iarg2 + var i2: Int? = iarg1 or iarg2 + var i3: Int? = iarg1 xor iarg2 + var i4: Int? = iarg1.inv() + var i5: Int? = iarg1 shl 16 + var i6: Int? = iarg1 shr 16 + var i7: Int? = iarg1 ushr 16 + + if (i1 != 0x44544454.toInt()) return "fail: Int.and" + if (i2 != 0xFDDEFDDE.toInt()) return "fail: Int.or" + if (i3 != 0xB98AB98A.toInt()) return "fail: Int.xor" + if (i4 != 0x23A923A9.toInt()) return "fail: Int.inv" + if (i5 != 0xDC560000.toInt()) return "fail: Int.shl" + if (i6 != 0xFFFFDC56.toInt()) return "fail: Int.shr" + if (i7 != 0x0000DC56.toInt()) return "fail: Int.ushr" + + + // TODO: Use long hex constants after KT-4749 is fixed + var larg1: Long = (0xDC56DC56L shl 32) + 0xDC56DC56 // !!!! + var larg2: Long = 0x65DC65DC65DC65DC + var l1: Long? = larg1 and larg2 + var l2: Long? = larg1 or larg2 + var l3: Long? = larg1 xor larg2 + var l4: Long? = larg1.inv() + var l5: Long? = larg1 shl 32 + var l6: Long? = larg1 shr 32 + var l7: Long? = larg1 ushr 32 + + if (l1 != 0x4454445444544454) return "fail: Long.and" + if (l2 != (0xFDDEFDDEL shl 32) + 0xFDDEFDDE) return "fail: Long.or" + if (l3 != (0xB98AB98AL shl 32) + 0xB98AB98A) return "fail: Long.xor" + if (l4 != 0x23A923A923A923A9) return "fail: Long.inv" + if (l5 != (0xDC56DC56L shl 32)/*!!!*/) return "fail: Long.shl" + if (l6 != (0xFFFFFFFFL shl 32) + 0xDC56DC56) return "fail: Long.shr" + if (l7 != (0x00000000L shl 32) + 0xDC56DC56.toLong()) return "fail: Long.ushr" + + var sarg1: Short = 0xDC56.toShort() + var sarg2: Short = 0x65DC.toShort() + var s1: Short? = sarg1 and sarg2 + var s2: Short? = sarg1 or sarg2 + var s3: Short? = sarg1 xor sarg2 + var s4: Short? = sarg1.inv() + + if (s1 != 0x4454.toShort()) return "fail: Short.and" + if (s2 != 0xFDDE.toShort()) return "fail: Short.or" + if (s3 != 0xB98A.toShort()) return "fail: Short.xor" + if (s4 != 0x23A9.toShort()) return "fail: Short.inv" + + var barg1: Byte = 0xDC.toByte() + var barg2: Byte = 0x65.toByte() + var b1: Byte? = barg1 and barg2 + var b2: Byte? = barg1 or barg2 + var b3: Byte? = barg1 xor barg2 + var b4: Byte? = barg1.inv() + + if (b1 != 0x44.toByte()) return "fail: Byte.and" + if (b2 != 0xFD.toByte()) return "fail: Byte.or" + if (b3 != 0xB9.toByte()) return "fail: Byte.xor" + if (b4 != 0x23.toByte()) return "fail: Byte.inv" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/binaryOp/call.kt b/backend.native/tests/external/codegen/blackbox/binaryOp/call.kt new file mode 100644 index 00000000000..0f3d0139001 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/binaryOp/call.kt @@ -0,0 +1,21 @@ +fun box(): String { + val a1: Byte = 1.plus(1) + val a2: Short = 1.plus(1) + val a3: Int = 1.plus(1) + val a4: Long = 1.plus(1) + val a5: Double = 1.0.plus(1) + val a6: Float = 1f.plus(1) + val a7: Char = 'A'.plus(1) + val a8: Int = 'B'.minus('A') + + if (a1 != 2.toByte()) return "fail 1" + if (a2 != 2.toShort()) return "fail 2" + if (a3 != 2) return "fail 3" + if (a4 != 2L) return "fail 4" + if (a5 != 2.0) return "fail 5" + if (a6 != 2f) return "fail 6" + if (a7 != 'B') return "fail 7" + if (a8 != 1) return "fail 8" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/binaryOp/callAny.kt b/backend.native/tests/external/codegen/blackbox/binaryOp/callAny.kt new file mode 100644 index 00000000000..7969cb5ec79 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/binaryOp/callAny.kt @@ -0,0 +1,21 @@ +fun box(): String { + val a1: Any = 1.toByte().plus(1) + val a2: Any = 1.toShort().plus(1) + val a3: Any = 1.plus(1) + val a4: Any = 1L.plus(1) + val a5: Any = 1.0.plus(1) + val a6: Any = 1f.plus(1) + val a7: Any = 'A'.plus(1) + val a8: Any = 'B'.minus('A') + + if (a1 !is Int || a1 != 2) return "fail 1" + if (a2 !is Int || a2 != 2) return "fail 2" + if (a3 !is Int || a3 != 2) return "fail 3" + if (a4 !is Long || a4 != 2L) return "fail 4" + if (a5 !is Double || a5 != 2.0) return "fail 5" + if (a6 !is Float || a6 != 2f) return "fail 6" + if (a7 !is Char || a7 != 'B') return "fail 7" + if (a8 !is Int || a8 != 1) return "fail 8" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/binaryOp/callNullable.kt b/backend.native/tests/external/codegen/blackbox/binaryOp/callNullable.kt new file mode 100644 index 00000000000..0167a38ed04 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/binaryOp/callNullable.kt @@ -0,0 +1,21 @@ +fun box(): String { + val a1: Byte? = 1.plus(1) + val a2: Short? = 1.plus(1) + val a3: Int? = 1.plus(1) + val a4: Long? = 1.plus(1) + val a5: Double? = 1.0.plus(1) + val a6: Float? = 1f.plus(1) + val a7: Char? = 'A'.plus(1) + val a8: Int? = 'B'.minus('A') + + if (a1!! != 2.toByte()) return "fail 1" + if (a2!! != 2.toShort()) return "fail 2" + if (a3!! != 2) return "fail 3" + if (a4!! != 2L) return "fail 4" + if (a5!! != 2.0) return "fail 5" + if (a6!! != 2f) return "fail 6" + if (a7!! != 'B') return "fail 7" + if (a8!! != 1) return "fail 8" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/binaryOp/compareWithBoxedDouble.kt b/backend.native/tests/external/codegen/blackbox/binaryOp/compareWithBoxedDouble.kt new file mode 100644 index 00000000000..553773be648 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/binaryOp/compareWithBoxedDouble.kt @@ -0,0 +1,20 @@ +// IGNORE_BACKEND: JS +// reason - multifile tests are not supported in JS tests +// IGNORE_BACKEND: NATIVE +// reason - no java interop. Consider testing by another way + +//FILE: Holder.kt + +class Holder { + public Double value; + public Holder(Double value) { this.value = value; } +} + +//FILE: test.kt + +import Holder + +fun box(): String { + val j = Holder(0.99) + return if (j.value > 0) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/binaryOp/compareWithBoxedLong.kt b/backend.native/tests/external/codegen/blackbox/binaryOp/compareWithBoxedLong.kt new file mode 100644 index 00000000000..14a07fe1eb3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/binaryOp/compareWithBoxedLong.kt @@ -0,0 +1,15 @@ +// IGNORE_BACKEND: JS +// reason - multifile tests are not supported in JS tests +//FILE: JavaClass.java + +class JavaClass { + public static Long get() { return 2364137526064485012L; } +} + +//FILE: test.kt + +import JavaClass + +fun box(): String { + return if (JavaClass.get() > 0) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/binaryOp/divisionByZero.kt b/backend.native/tests/external/codegen/blackbox/binaryOp/divisionByZero.kt new file mode 100644 index 00000000000..1daa188f030 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/binaryOp/divisionByZero.kt @@ -0,0 +1,14 @@ +// IGNORE_BACKEND: JS +// reason - no ArithmeticException in JS +fun box(): String { + val a1 = 0 + val a2 = try { 1 / 0 } catch(e: ArithmeticException) { 0 } + val a3 = try { 1 / a1 } catch(e: ArithmeticException) { 0 } + val a4 = try { 1 / a2 } catch(e: ArithmeticException) { 0 } + val a5 = try { 2 * (1 / 0) } catch(e: ArithmeticException) { 0 } + val a6 = try { 2 * 1 / 0 } catch(e: ArithmeticException) { 0 } + + try { val s1 = "${2 * (1 / 0) }" } catch(e: ArithmeticException) { } + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/binaryOp/intrinsic.kt b/backend.native/tests/external/codegen/blackbox/binaryOp/intrinsic.kt new file mode 100644 index 00000000000..7434a7848e5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/binaryOp/intrinsic.kt @@ -0,0 +1,21 @@ +fun box(): String { + val a1: Byte = 1 + 1 + val a2: Short = 1 + 1 + val a3: Int = 1 + 1 + val a4: Long = 1 + 1 + val a5: Double = 1.0 + 1 + val a6: Float = 1f + 1 + val a7: Char = 'A' + 1 + val a8: Int = 'B' - 'A' + + if (a1 != 2.toByte()) return "fail 1" + if (a2 != 2.toShort()) return "fail 2" + if (a3 != 2) return "fail 3" + if (a4 != 2L) return "fail 4" + if (a5 != 2.0) return "fail 5" + if (a6 != 2f) return "fail 6" + if (a7 != 'B') return "fail 7" + if (a8 != 1) return "fail 8" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/binaryOp/intrinsicAny.kt b/backend.native/tests/external/codegen/blackbox/binaryOp/intrinsicAny.kt new file mode 100644 index 00000000000..fd240b08a58 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/binaryOp/intrinsicAny.kt @@ -0,0 +1,21 @@ +fun box(): String { + val a1: Any = 1.toByte() + 1 + val a2: Any = 1.toShort() + 1 + val a3: Any = 1 + 1 + val a4: Any = 1L + 1 + val a5: Any = 1.0 + 1 + val a6: Any = 1f + 1 + val a7: Any = 'A' + 1 + val a8: Any = 'B' - 'A' + + if (a1 !is Int || a1 != 2) return "fail 1" + if (a2 !is Int || a2 != 2) return "fail 2" + if (a3 !is Int || a3 != 2) return "fail 3" + if (a4 !is Long || a4 != 2L) return "fail 4" + if (a5 !is Double || a5 != 2.0) return "fail 5" + if (a6 !is Float || a6 != 2f) return "fail 6" + if (a7 !is Char || a7 != 'B') return "fail 7" + if (a8 !is Int || a8 != 1) return "fail 8" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/binaryOp/intrinsicNullable.kt b/backend.native/tests/external/codegen/blackbox/binaryOp/intrinsicNullable.kt new file mode 100644 index 00000000000..fdfc98f3bb4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/binaryOp/intrinsicNullable.kt @@ -0,0 +1,21 @@ +fun box(): String { + val a1: Byte? = 1 + 1 + val a2: Short? = 1 + 1 + val a3: Int? = 1 + 1 + val a4: Long? = 1 + 1 + val a5: Double? = 1.0 + 1 + val a6: Float? = 1f + 1 + val a7: Char? = 'A' + 1 + val a8: Int? = 'B' - 'A' + + if (a1!! != 2.toByte()) return "fail 1" + if (a2!! != 2.toShort()) return "fail 2" + if (a3!! != 2) return "fail 3" + if (a4!! != 2L) return "fail 4" + if (a5!! != 2.0) return "fail 5" + if (a6!! != 2f) return "fail 6" + if (a7!! != 'B') return "fail 7" + if (a8!! != 1) return "fail 8" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/binaryOp/kt11163.kt b/backend.native/tests/external/codegen/blackbox/binaryOp/kt11163.kt new file mode 100644 index 00000000000..6a20534e140 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/binaryOp/kt11163.kt @@ -0,0 +1,12 @@ +operator fun Int.compareTo(c: Char) = 0 + +fun foo(x: Int, y: Char): String { + if (x < y) { + throw Error() + } + return "${y}K" +} + +fun box(): String { + return foo(42, 'O') +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/binaryOp/kt6747_identityEquals.kt b/backend.native/tests/external/codegen/blackbox/binaryOp/kt6747_identityEquals.kt new file mode 100644 index 00000000000..cf261d60b7a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/binaryOp/kt6747_identityEquals.kt @@ -0,0 +1,9 @@ +class Test { + fun check(a: Any?): String { + if (this === a) return "Fail 1" + if (!(this !== a)) return "Fail 2" + return "OK" + } +} + +fun box(): String = Test().check("String") diff --git a/backend.native/tests/external/codegen/blackbox/binaryOp/overflowChar.kt b/backend.native/tests/external/codegen/blackbox/binaryOp/overflowChar.kt new file mode 100644 index 00000000000..0f06f4969fd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/binaryOp/overflowChar.kt @@ -0,0 +1,10 @@ +fun box(): String { + val c1: Char = 0.toChar() + val c2 = c1 - 1 + if (c2 < c1) return "fail: 0.toChar() - 1 should overflow to positive." + + val c3 = c2 + 1 + if (c3 > c2) return "fail: FFFF.toChar() + 1 should overflow to zero." + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/binaryOp/overflowInt.kt b/backend.native/tests/external/codegen/blackbox/binaryOp/overflowInt.kt new file mode 100644 index 00000000000..4d5b899987f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/binaryOp/overflowInt.kt @@ -0,0 +1,11 @@ +fun box(): String { + val i1: Int = Int.MAX_VALUE + val i2 = i1 + 1 + if (i2 > i1) return "fail: Int.MAX_VALUE + 1 should overflow to negative." + + val i3: Int = Int.MIN_VALUE + val i4 = i3 - 1 + if (i4 < i3) return "fail: Int.MIN_VALUE - 1 should overflow to positive." + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/binaryOp/overflowLong.kt b/backend.native/tests/external/codegen/blackbox/binaryOp/overflowLong.kt new file mode 100644 index 00000000000..28d37ab1c12 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/binaryOp/overflowLong.kt @@ -0,0 +1,14 @@ +fun box(): String { + val a: Long = 2147483647 + 1 + if (a != -2147483648L) return "fail: in this case we should add to ints and than cast the result to long - overflow expected" + + val l1 = Long.MAX_VALUE + val l2 = l1 + 1 + if (l2 > l1) return "fail: Long.MAX_VALUE + 1 should overflow to negative." + + val l3 = Long.MIN_VALUE + val l4 = l3 - 1 + if (l4 < l3) return "fail: Long.MIN_VALUE - 1 should overflow to positive." + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/boxingOptimization/casts.kt b/backend.native/tests/external/codegen/blackbox/boxingOptimization/casts.kt new file mode 100644 index 00000000000..47ce676892b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/boxingOptimization/casts.kt @@ -0,0 +1,18 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun foo(x : R?, block : (R?) -> T) : T { + return block(x) +} + +fun box() : String { + assertEquals(1L, foo(1) { x -> x!!.toLong() }) + assertEquals(1.toShort(), foo(1) { x -> x!!.toShort() }) + assertEquals(1.toByte(), foo(1L) { x -> x!!.toByte() }) + assertEquals(1.toShort(), foo(1L) { x -> x!!.toShort() }) + assertEquals('a'.toDouble(), foo('a') { x -> x!!.toDouble() }) + assertEquals(1.0.toByte(), foo(1.0) { x -> x!!.toByte() }) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/boxingOptimization/checkcastAndInstanceOf.kt b/backend.native/tests/external/codegen/blackbox/boxingOptimization/checkcastAndInstanceOf.kt new file mode 100644 index 00000000000..86e8dc6bec7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/boxingOptimization/checkcastAndInstanceOf.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun foo(x : R, y : R, block : (R) -> T) : T { + val a = x is Number + val b = x is Object + + val b1 = x as Object + + if (a && b) { + return block(x) + } else { + return block(y) + } +} + +fun box() : String { + assertEquals(1, foo(1, 2) { x -> x as Int }) + assertEquals("def", foo("abc", "def") { x -> x as String }) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/boxingOptimization/fold.kt b/backend.native/tests/external/codegen/blackbox/boxingOptimization/fold.kt new file mode 100644 index 00000000000..7bb1608458b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/boxingOptimization/fold.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box() : String { + val x = LongArray(5) + for (i in 0..4) { + x[i] = (i + 1).toLong() + } + + assertEquals(15L, x.fold(0L) { x, y -> x + y }) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/boxingOptimization/foldRange.kt b/backend.native/tests/external/codegen/blackbox/boxingOptimization/foldRange.kt new file mode 100644 index 00000000000..1127090af9e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/boxingOptimization/foldRange.kt @@ -0,0 +1,11 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + val result = (1..5).fold(0) { x, y -> x + y } + + assertEquals(15, result) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/boxingOptimization/kt5493.kt b/backend.native/tests/external/codegen/blackbox/boxingOptimization/kt5493.kt new file mode 100644 index 00000000000..efd7e94a5f7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/boxingOptimization/kt5493.kt @@ -0,0 +1,8 @@ +fun box() : String { + try { + return "OK" + } + finally { + null?.toString() + } +} diff --git a/backend.native/tests/external/codegen/blackbox/boxingOptimization/kt5588.kt b/backend.native/tests/external/codegen/blackbox/boxingOptimization/kt5588.kt new file mode 100644 index 00000000000..ece5914c504 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/boxingOptimization/kt5588.kt @@ -0,0 +1,10 @@ +fun box() : String { + val s = "notA" + val id = when (s) { + "a" -> 1 + else -> null + } + + if (id == null) return "OK" + return "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/boxingOptimization/kt5844.kt b/backend.native/tests/external/codegen/blackbox/boxingOptimization/kt5844.kt new file mode 100644 index 00000000000..acc4da5c729 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/boxingOptimization/kt5844.kt @@ -0,0 +1,29 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun test1() { + val u = when (true) { + true -> 42 + else -> 1.0 + } + + assertEquals(42, u) +} + +fun test2() { + val u = 1L.let { + when (it) { + is Long -> if (it.toLong() == 2L) it.toLong() else it * 2L // CompilationException + else -> it.toDouble() + } + } + + assertEquals(2L, u) +} + +fun box(): String { + test1() + test2() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/boxingOptimization/kt6047.kt b/backend.native/tests/external/codegen/blackbox/boxingOptimization/kt6047.kt new file mode 100644 index 00000000000..a397903567e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/boxingOptimization/kt6047.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun checkLongAB5E(x: Long) = assertEquals(0xAB5EL, x) +fun checkDouble1(y: Double) = assertEquals(1.0, y) +fun checkByte10(z: Byte) = assertEquals(10.toByte(), z) + +fun box(): String { + val x = java.lang.Long.valueOf("AB5E", 16) + checkLongAB5E(x) + + val y = java.lang.Double.valueOf("1.0") + checkDouble1(y) + + val z = java.lang.Byte.valueOf("A", 16) + checkByte10(z) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/boxingOptimization/kt6842.kt b/backend.native/tests/external/codegen/blackbox/boxingOptimization/kt6842.kt new file mode 100644 index 00000000000..e3162a626a3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/boxingOptimization/kt6842.kt @@ -0,0 +1,9 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + val x = (10L..50).map { it * 40L } + assertEquals(400L, x.first()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/boxingOptimization/nullCheck.kt b/backend.native/tests/external/codegen/blackbox/boxingOptimization/nullCheck.kt new file mode 100644 index 00000000000..4ba74af4165 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/boxingOptimization/nullCheck.kt @@ -0,0 +1,17 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun foo(x : R?, y : R?, block : (R?) -> T) : T { + if (x == null) { + return block(x) + } else { + return block(y) + } +} + +fun box() : String { + assertEquals(3, foo(1, 2) { x -> if (x != null) 3 else 4 }) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/boxingOptimization/progressions.kt b/backend.native/tests/external/codegen/blackbox/boxingOptimization/progressions.kt new file mode 100644 index 00000000000..6892c12e89d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/boxingOptimization/progressions.kt @@ -0,0 +1,33 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box() : String { + + val result1 = (1..100).count { x -> x % 2 == 0 } + val result2 = (1..100).filter { x -> x % 2 == 0 }.size + assertEquals(result1, 50) + assertEquals(result2, 50) + + val result3 = (1..100).map { x -> 2 * x }.count { x -> x % 2 == 0 } + val result4 = (1..100).map { x -> 2 * x }.filter { x -> x % 2 == 0 }.size + assertEquals(result3, 100) + assertEquals(result4, 100) + + val result5 = (1L..100L).count { x -> x % 2 == 0L } + val result6 = (1L..100L).filter { x -> x % 2 == 0L }.size + assertEquals(result5, 50) + assertEquals(result6, 50) + + val result7 = (1L..100L).map { x -> 2 * x }.count { x -> x % 2 == 0L } + val result8 = (1L..100L).map { x -> 2 * x }.filter { x -> x % 2 == 0L }.size + assertEquals(result7, 100) + assertEquals(result8, 100) + + val result9 = (0..10).reduce { total, next -> total + next } + val result10 = (0L..10L).reduce { total, next -> total + next } + assertEquals(result9, 55) + assertEquals(result10, 55L) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/boxingOptimization/safeCallWithElvis.kt b/backend.native/tests/external/codegen/blackbox/boxingOptimization/safeCallWithElvis.kt new file mode 100644 index 00000000000..1ffec309237 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/boxingOptimization/safeCallWithElvis.kt @@ -0,0 +1,29 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +class A(val x : Int, val y : A?) + +fun check(a : A?) : Int { + return a?.y?.x ?: (a?.x ?: 3) +} + +fun checkLeftAssoc(a : A?) : Int { + return (a?.y?.x ?: a?.x) ?: 3 +} + +fun box() : String { + val a1 = A(2, A(1, null)) + val a2 = A(2, null) + val a3 = null + + assertEquals(1, check(a1)) + assertEquals(2, check(a2)) + assertEquals(3, check(a3)) + + assertEquals(1, checkLeftAssoc(a1)) + assertEquals(2, checkLeftAssoc(a2)) + assertEquals(3, checkLeftAssoc(a3)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/boxingOptimization/simple.kt b/backend.native/tests/external/codegen/blackbox/boxingOptimization/simple.kt new file mode 100644 index 00000000000..fbe93a5233a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/boxingOptimization/simple.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun foo(x : R, block : (R) -> R) : R { + return block(x) +} + +fun box() : String { + val result = foo(1) { x -> x + 1 } + assertEquals(2, result) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/boxingOptimization/simpleUninitializedMerge.kt b/backend.native/tests/external/codegen/blackbox/boxingOptimization/simpleUninitializedMerge.kt new file mode 100644 index 00000000000..9612abbe1bb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/boxingOptimization/simpleUninitializedMerge.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + var result = 0 + if (1 == 1) { + val x: Int? = 1 + result += x!! + } + + assertEquals(1, result) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/boxingOptimization/unsafeRemoving.kt b/backend.native/tests/external/codegen/blackbox/boxingOptimization/unsafeRemoving.kt new file mode 100644 index 00000000000..e11a594361d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/boxingOptimization/unsafeRemoving.kt @@ -0,0 +1,35 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun returningBoxed() : Int? = 1 +fun acceptingBoxed(x : Int?) : Int ? = x + +class A(var x : Int? = null) + +fun box() : String { + assertEquals(1, returningBoxed()) + assertEquals(1, acceptingBoxed(1)) + + val a = A() + a.x = 1 + assertEquals(1, a.x) + + val b = Array(1, { null }) + b[0] = 1 + assertEquals(1, b[0]) + + val x: Int? = 1 + assertEquals(1, x!!.hashCode()) + + val y: Int? = 1000 + val z: Int? = 1000 + val res = y === z + + val c1: Any = if (1 == 1) 0 else "abc" + val c2: Any = if (1 != 1) 0 else "abc" + assertEquals(0, c1) + assertEquals("abc", c2) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/boxingOptimization/variables.kt b/backend.native/tests/external/codegen/blackbox/boxingOptimization/variables.kt new file mode 100644 index 00000000000..18f6bf3d71e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/boxingOptimization/variables.kt @@ -0,0 +1,23 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun foo(x : R, block : (R) -> T) : T { + var y = x + var z = y + z = x + return block(z) +} + +fun box() : String { + assertEquals(1, foo(1) { x -> x }) + assertEquals(1f, foo(1f) { x -> x }) + assertEquals(1L, foo(1L) { x -> x }) + assertEquals(1.toDouble(), foo(1.toDouble()) { x -> x }) + assertEquals(1.toShort(), foo(1.toShort()) { x -> x }) + assertEquals(1.toByte(), foo(1.toByte()) { x -> x }) + assertEquals('a', foo('a') { x -> x }) + assertEquals(true, foo(true) { x -> x }) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/complexMultiInheritance.kt b/backend.native/tests/external/codegen/blackbox/bridges/complexMultiInheritance.kt new file mode 100644 index 00000000000..227bd67042c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/complexMultiInheritance.kt @@ -0,0 +1,25 @@ +open class A { + open fun foo(): Any = "A" +} + +open class C : A() { + override fun foo(): Int = 222 +} + +interface D { + fun foo(): Number +} + +class E : C(), D + +fun box(): String { + val e = E() + if (e.foo() != 222) return "Fail 1" + val d: D = e + val c: C = e + val a: A = e + if (d.foo() != 222) return "Fail 2" + if (c.foo() != 222) return "Fail 3" + if (a.foo() != 222) return "Fail 4" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/complexTraitImpl.kt b/backend.native/tests/external/codegen/blackbox/bridges/complexTraitImpl.kt new file mode 100644 index 00000000000..ff5edc8750b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/complexTraitImpl.kt @@ -0,0 +1,33 @@ +// WITH_RUNTIME + +abstract class A { + abstract fun foo(): List +} + +interface B { + fun foo(): ArrayList = ArrayList(listOf("B")) +} + +open class C : A(), B { + override fun foo(): ArrayList = super.foo() +} + +interface D { + fun foo(): Collection +} + +class E : D, C() + +fun box(): String { + val e = E() + var r = e.foo()[0] + val d: D = e + val c: C = e + val b: B = e + val a: A = e + r += d.foo().iterator().next() + r += c.foo()[0] + r += b.foo()[0] + r += a.foo()[0] + return if (r == "BBBBB") "OK" else "Fail: $r" +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/delegation.kt b/backend.native/tests/external/codegen/blackbox/bridges/delegation.kt new file mode 100644 index 00000000000..29dfbecf8a6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/delegation.kt @@ -0,0 +1,14 @@ +interface A { + fun foo(): T +} + +class B : A { + override fun foo() = "OK" +} + +class C(a: A) : A by a + +fun box(): String { + val a: A = C(B()) + return a.foo() +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/delegationComplex.kt b/backend.native/tests/external/codegen/blackbox/bridges/delegationComplex.kt new file mode 100644 index 00000000000..77af8d7e9b5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/delegationComplex.kt @@ -0,0 +1,17 @@ +open class Content() { + override fun toString() = "OK" +} + +interface Box { + fun get(): E +} + +interface ContentBox : Box + +object Impl : ContentBox { + override fun get(): Content = Content() +} + +class ContentBoxDelegate() : ContentBox by (Impl as ContentBox) + +fun box() = ContentBoxDelegate().get().toString() diff --git a/backend.native/tests/external/codegen/blackbox/bridges/delegationComplexWithList.kt b/backend.native/tests/external/codegen/blackbox/bridges/delegationComplexWithList.kt new file mode 100644 index 00000000000..caf8be2c5dd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/delegationComplexWithList.kt @@ -0,0 +1,18 @@ +// WITH_RUNTIME + +open class Content() { + override fun toString() = "OK" +} + +interface ContentBox : List + +object Impl : ContentBox , AbstractList() { + override fun get(index: Int) = Content() + + override val size: Int + get() = throw UnsupportedOperationException() +} + +class ContentBoxDelegate() : ContentBox by (Impl as ContentBox) + +fun box() = ContentBoxDelegate()[0].toString() diff --git a/backend.native/tests/external/codegen/blackbox/bridges/delegationProperty.kt b/backend.native/tests/external/codegen/blackbox/bridges/delegationProperty.kt new file mode 100644 index 00000000000..8192c4f4532 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/delegationProperty.kt @@ -0,0 +1,15 @@ +interface A { + var result: T +} + +class B(a: A): A by a + +fun box(): String { + val o = object : A { + override var result = "Fail" + } + val b: A = B(o) + b.result = "OK" + if (b.result != "OK") return "Fail" + return b.result +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/diamond.kt b/backend.native/tests/external/codegen/blackbox/bridges/diamond.kt new file mode 100644 index 00000000000..ef1990bf937 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/diamond.kt @@ -0,0 +1,26 @@ +interface A { + fun foo(t: T, u: U) = "A" +} + +interface B : A + +interface C : A + +class Z : B, C { + override fun foo(t: String, u: Int) = "Z" +} + + +fun box(): String { + val z = Z() + val c: C = z + val b: B = z + val a: A = z + return when { + z.foo("", 0) != "Z" -> "Fail #1" + c.foo("", 0) != "Z" -> "Fail #2" + b.foo("", 0) != "Z" -> "Fail #3" + a.foo("", 0) != "Z" -> "Fail #4" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/fakeCovariantOverride.kt b/backend.native/tests/external/codegen/blackbox/bridges/fakeCovariantOverride.kt new file mode 100644 index 00000000000..e62de29d55a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/fakeCovariantOverride.kt @@ -0,0 +1,19 @@ +// KT-4145 + +interface A { + fun foo(): Any +} + +open class B { + fun foo(): String = "A" +} + +open class C: B(), A + +fun box(): String { + val a: A = C() + if (a.foo() != "A") return "Fail 1" + if ((a as B).foo() != "A") return "Fail 2" + if ((a as C).foo() != "A") return "Fail 3" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/fakeGenericCovariantOverride.kt b/backend.native/tests/external/codegen/blackbox/bridges/fakeGenericCovariantOverride.kt new file mode 100644 index 00000000000..ffff9f297e4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/fakeGenericCovariantOverride.kt @@ -0,0 +1,22 @@ +// KT-3985 + +interface Trait { + fun f(): T +} + +open class Class { + fun f(): String = throw UnsupportedOperationException() +} + +class Foo: Class(), Trait { +} + +fun box(): String { + val t: Trait = Foo() + try { + t.f() + } catch (e: UnsupportedOperationException) { + return "OK" + } + return "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/fakeGenericCovariantOverrideWithDelegation.kt b/backend.native/tests/external/codegen/blackbox/bridges/fakeGenericCovariantOverrideWithDelegation.kt new file mode 100644 index 00000000000..450ad185175 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/fakeGenericCovariantOverrideWithDelegation.kt @@ -0,0 +1,32 @@ +interface A { + fun foo(t: T): String +} + +interface B { + fun foo(t: Int) = "B" +} + +class Z : B + +class Z1 : A, B by Z() + +class Z2 : B by Z(), A + +fun box(): String { + val z1 = Z1() + val z2 = Z2() + val z1a: A = z1 + val z1b: B = z1 + val z2a: A = z2 + val z2b: B = z2 + + return when { + z1.foo( 0) != "B" -> "Fail #1" + z1a.foo( 0) != "B" -> "Fail #2" + z1b.foo( 0) != "B" -> "Fail #3" + z2.foo( 0) != "B" -> "Fail #4" + z2a.foo( 0) != "B" -> "Fail #5" + z2b.foo( 0) != "B" -> "Fail #6" + else -> "OK" + } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/bridges/fakeOverrideOfTraitImpl.kt b/backend.native/tests/external/codegen/blackbox/bridges/fakeOverrideOfTraitImpl.kt new file mode 100644 index 00000000000..7827f53a892 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/fakeOverrideOfTraitImpl.kt @@ -0,0 +1,31 @@ +var result = "" + +interface D1 { + fun foo(): D1 { + result += "D1" + return this + } +} + +interface F2 : D1 + +interface D3 : F2 { + override fun foo(): D3 { + result += "D3" + return this + } +} + +class D4 : D3 + +fun box(): String { + val x = D4() + x.foo() + val d3: D3 = x + val f2: F2 = x + val d1: D1 = x + d3.foo() + f2.foo() + d1.foo() + return if (result == "D3D3D3D3") "OK" else "Fail: $result" +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/fakeOverrideWithSeveralSuperDeclarations.kt b/backend.native/tests/external/codegen/blackbox/bridges/fakeOverrideWithSeveralSuperDeclarations.kt new file mode 100644 index 00000000000..c9844928db7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/fakeOverrideWithSeveralSuperDeclarations.kt @@ -0,0 +1,30 @@ +interface D1 { + fun foo(): Any +} + +interface D2 { + fun foo(): Number +} + +interface F3 : D1, D2 + +open class D4 { + fun foo(): Int = 42 +} + +class F5 : F3, D4() + +fun box(): String { + val z = F5() + var result = z.foo() + val d4: D4 = z + val f3: F3 = z + val d2: D2 = z + val d1: D1 = z + + result += d4.foo() + result += f3.foo() as Int + result += d2.foo() as Int + result += d1.foo() as Int + return if (result == 5 * 42) "OK" else "Fail: $result" +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/fakeOverrideWithSynthesizedImplementation.kt b/backend.native/tests/external/codegen/blackbox/bridges/fakeOverrideWithSynthesizedImplementation.kt new file mode 100644 index 00000000000..075bbca0443 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/fakeOverrideWithSynthesizedImplementation.kt @@ -0,0 +1,18 @@ +open class A(val value: String) { + fun component1() = value +} + +interface B { + fun component1(): Any +} + +class C(value: String) : A(value), B + +fun box(): String { + val c = C("OK") + val b: B = c + val a: A = c + if (b.component1() != "OK") return "Fail 1" + if (a.component1() != "OK") return "Fail 2" + return c.component1() +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/genericProperty.kt b/backend.native/tests/external/codegen/blackbox/bridges/genericProperty.kt new file mode 100644 index 00000000000..be4000a62e3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/genericProperty.kt @@ -0,0 +1,19 @@ +open class A { + var size: T = 56 as T +} + +interface C { + var size: Int +} + +class B : C, A() + +fun box(): String { + val b = B() + if (b.size != 56) return "fail 1: ${b.size}" + + b.size = 55 + if (b.size != 55) return "fail 2: ${b.size}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/jsName.kt b/backend.native/tests/external/codegen/blackbox/bridges/jsName.kt new file mode 100644 index 00000000000..c024e4eed2e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/jsName.kt @@ -0,0 +1,59 @@ +// TARGET_BACKEND: JS +package foo + +interface A { + @JsName("foo") fun foo(value: Int): String +} + +interface B { + @JsName("bar") fun foo(value: Int): String +} + +open class C : A, B { + override fun foo(value: Int) = "C.foo($value)" +} + +class CDerived : C() { + override fun foo(value: Int) = "CDerived.foo($value)" +} + +open class D { + open fun foo(value: Int) = "D.foo($value)" +} + +class E : D(), A, B + +fun box(): String { + val a: A = C() + assertEquals("C.foo(55)", a.foo(55)) + + val b: B = C() + assertEquals("C.foo(23)", b.foo(23)) + + val a2: A = CDerived() + assertEquals("CDerived.foo(55)", a2.foo(55)) + + val b2: B = CDerived() + assertEquals("CDerived.foo(23)", b2.foo(23)) + + val d: dynamic = C() + assertEquals("C.foo(42)", d.foo(42)) + assertEquals("C.foo(99)", d.bar(99)) + + val d2: dynamic = CDerived() + assertEquals("CDerived.foo(42)", d2.foo(42)) + assertEquals("CDerived.foo(99)", d2.bar(99)) + + val da: A = E() + assertEquals("D.foo(55)", da.foo(55)) + + val db: B = E() + assertEquals("D.foo(23)", db.foo(23)) + + val dd: dynamic = E() + assertEquals("D.foo(42)", dd.foo(42)) + assertEquals("D.foo(99)", dd.bar(99)) + assertEquals("D.foo(88)", dd.`foo_za3lpa$`(88)) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/bridges/jsNative.kt b/backend.native/tests/external/codegen/blackbox/bridges/jsNative.kt new file mode 100644 index 00000000000..b13d97886dd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/jsNative.kt @@ -0,0 +1,44 @@ +// TARGET_BACKEND: JS +package foo + +external interface A { + fun foo(value: Int): String +} + +interface B { + fun foo(value: Int): String +} + +class C : A, B { + override fun foo(value: Int) = "C.foo($value)" +} + +open class D { + open fun foo(value: Int) = "D.foo($value)" +} + +class E : D(), A, B + +fun box(): String { + val a: A = C() + assertEquals("C.foo(55)", a.foo(55)) + + val b: B = C() + assertEquals("C.foo(23)", b.foo(23)) + + val d: dynamic = C() + assertEquals("C.foo(42)", d.foo(42)) + assertEquals("C.foo(99)", d.`foo_za3lpa$`(99)) + + val da: A = E() + assertEquals("D.foo(55)", da.foo(55)) + + val db: B = E() + assertEquals("D.foo(23)", db.foo(23)) + + val dd: dynamic = E() + assertEquals("D.foo(42)", dd.foo(42)) + assertEquals("D.foo(99)", dd.`foo_za3lpa$`(99)) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/bridges/kt12416.kt b/backend.native/tests/external/codegen/blackbox/bridges/kt12416.kt new file mode 100644 index 00000000000..c50c81671f5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/kt12416.kt @@ -0,0 +1,41 @@ +interface A { + fun foo(t: T, u: Int) = "A" +} + +interface B { + fun foo(t: T, u: U) = "B" +} + +interface Z1 : A, B { + override fun foo(t: String, u: Int) = "Z1" +} + +interface Z2 : B, A { + override fun foo(t: String, u: Int) = "Z2" +} + +class Z1C : Z1 { + +} + +class Z2C : Z2 { + +} + +fun box(): String { + val z1 = Z1C() + val z2 = Z2C() + val z1a: A = z1 + val z1b: B = z1 + val z2a: A = z2 + val z2b: B = z2 + return when { + z1.foo("", 0) != "Z1" -> "Fail #1" + z1a.foo("", 0) != "Z1" -> "Fail #2" + z1b.foo("", 0) != "Z1" -> "Fail #3" //FAIL + z2.foo("", 0) != "Z2" -> "Fail #4" + z2a.foo("", 0) != "Z2" -> "Fail #5" + z2b.foo("", 0) != "Z2" -> "Fail #6" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/kt1939.kt b/backend.native/tests/external/codegen/blackbox/bridges/kt1939.kt new file mode 100644 index 00000000000..ad300dc796e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/kt1939.kt @@ -0,0 +1,12 @@ +abstract class Foo { + fun hello(id: T) = "Hi $id" +} + +interface Tr { + fun hello(s : String): String +} + +class Bar: Foo(), Tr { +} + +fun box(): String = if (Bar().hello("Reg") == "Hi Reg") "OK" else "Fail" diff --git a/backend.native/tests/external/codegen/blackbox/bridges/kt1959.kt b/backend.native/tests/external/codegen/blackbox/bridges/kt1959.kt new file mode 100644 index 00000000000..e7bfcbaa2c8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/kt1959.kt @@ -0,0 +1,13 @@ +open class A { + open fun f(args : Array) {} +} + +class B(): A() { + override fun f(args : Array) {} +} + +fun main(args: Array) { + B() +} + +fun box(): String = "OK" diff --git a/backend.native/tests/external/codegen/blackbox/bridges/kt2498.kt b/backend.native/tests/external/codegen/blackbox/bridges/kt2498.kt new file mode 100644 index 00000000000..7d0feab1058 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/kt2498.kt @@ -0,0 +1,19 @@ +open class BaseStringList: ArrayList() { +} + +class StringList: BaseStringList() { + public override fun get(index: Int): String { + return "StringList.get()" + } +} + +fun box(): String { + val myStringList = StringList() + myStringList.add("first element") + if (myStringList.get(0) != "StringList.get()") return "Fail #1" + val b: BaseStringList = myStringList + val a: ArrayList = myStringList + if (b.get(0) != "StringList.get()") return "Fail #2" + if (a.get(0) != "StringList.get()") return "Fail #3" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/kt2702.kt b/backend.native/tests/external/codegen/blackbox/bridges/kt2702.kt new file mode 100644 index 00000000000..cbf5eebee68 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/kt2702.kt @@ -0,0 +1,14 @@ +open class A { + open fun foo(r: R): R {return r} +} + +open class B : A() { +} + +open class C : B() { + override fun foo(r: String): String { + return super.foo(r) + "K" + } +} + +fun box() = C().foo("O") diff --git a/backend.native/tests/external/codegen/blackbox/bridges/kt2833.kt b/backend.native/tests/external/codegen/blackbox/bridges/kt2833.kt new file mode 100644 index 00000000000..50a2989d904 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/kt2833.kt @@ -0,0 +1,17 @@ +package test + +public interface FunDependencyEdge { + val from: FunctionNode +} + +public interface FunctionNode + +public class FunctionNodeImpl : FunctionNode + +class FunDependencyEdgeImpl(override val from: FunctionNodeImpl): FunDependencyEdge { +} + +fun box(): String { + (FunDependencyEdgeImpl(FunctionNodeImpl()) as FunDependencyEdge).from + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/kt2920.kt b/backend.native/tests/external/codegen/blackbox/bridges/kt2920.kt new file mode 100644 index 00000000000..0f71953ba12 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/kt2920.kt @@ -0,0 +1,9 @@ +interface Tr { + val v: T +} + +class C : Tr { + override val v = "OK" +} + +fun box() = C().v diff --git a/backend.native/tests/external/codegen/blackbox/bridges/kt318.kt b/backend.native/tests/external/codegen/blackbox/bridges/kt318.kt new file mode 100644 index 00000000000..72e5991297c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/kt318.kt @@ -0,0 +1,24 @@ +var result = "" + +interface Base +open class Child : Base + +interface A { + fun foo(a : E) { + result += "A" + } +} + +class B : A { + override fun foo(a : E) { + result += "B" + } +} + +fun box(): String { + val b = B() + b.foo(Child()) + val a: A = b + a.foo(Child()) + return if (result == "BB") "OK" else "Fail: $result" +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/longChainOneBridge.kt b/backend.native/tests/external/codegen/blackbox/bridges/longChainOneBridge.kt new file mode 100644 index 00000000000..6d1d79c28e7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/longChainOneBridge.kt @@ -0,0 +1,32 @@ +open class A { + open fun foo(t: T) = "A" +} + +open class B : A() + +open class C : B() { + override fun foo(t: String) = "C" +} + +open class D : C() + +class Z : D() { + override fun foo(t: String) = "Z" +} + + +fun box(): String { + val z = Z() + val d: D = z + val c: C = z + val b: B = z + val a: A = z + return when { + z.foo("") != "Z" -> "Fail #1" + d.foo("") != "Z" -> "Fail #2" + c.foo("") != "Z" -> "Fail #3" + b.foo("") != "Z" -> "Fail #4" + a.foo("") != "Z" -> "Fail #5" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/manyTypeArgumentsSubstitutedSuccessively.kt b/backend.native/tests/external/codegen/blackbox/bridges/manyTypeArgumentsSubstitutedSuccessively.kt new file mode 100644 index 00000000000..82306ddf3f4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/manyTypeArgumentsSubstitutedSuccessively.kt @@ -0,0 +1,26 @@ +open class A { + open fun foo(t: T, u: U, v: V) = "A" +} + +open class B : A() + +open class C : B() + +class Z : C() { + override fun foo(t: String, u: Int, v: Double) = "Z" +} + + +fun box(): String { + val z = Z() + val c: C = z + val b: B = z + val a: A = z + return when { + z.foo("", 0, 0.0) != "Z" -> "Fail #1" + c.foo("", 0, 0.0) != "Z" -> "Fail #2" + b.foo("", 0, 0.0) != "Z" -> "Fail #3" + a.foo("", 0, 0.0) != "Z" -> "Fail #4" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/methodFromTrait.kt b/backend.native/tests/external/codegen/blackbox/bridges/methodFromTrait.kt new file mode 100644 index 00000000000..058109901d1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/methodFromTrait.kt @@ -0,0 +1,17 @@ +interface A { + fun foo(t: T, u: U) = "A" +} + +class Z : A { + override fun foo(t: T, u: Int) = "Z" +} + +fun box(): String { + val z = Z() + val a: A = z + return when { + z.foo(0, 0) != "Z" -> "Fail #1" + a.foo(0, 0) != "Z" -> "Fail #2" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/noBridgeOnMutableCollectionInheritance.kt b/backend.native/tests/external/codegen/blackbox/bridges/noBridgeOnMutableCollectionInheritance.kt new file mode 100644 index 00000000000..59e364fe37f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/noBridgeOnMutableCollectionInheritance.kt @@ -0,0 +1,23 @@ +// WITH_RUNTIME + +interface A { + fun foo(): Collection +} + +interface B : A { + override fun foo(): MutableCollection +} + +class C : B { + override fun foo(): MutableList = ArrayList(listOf("C")) +} + +fun box(): String { + val c = C() + var r = c.foo().iterator().next() + val b: B = c + val a: A = c + r += b.foo().iterator().next() + r += a.foo().iterator().next() + return if (r == "CCC") "OK" else "Fail: $r" +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/objectClone.kt b/backend.native/tests/external/codegen/blackbox/bridges/objectClone.kt new file mode 100644 index 00000000000..773f66e04c4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/objectClone.kt @@ -0,0 +1,23 @@ +// TARGET_BACKEND: JVM +import java.util.HashSet + +interface A : Set + +class B : A, HashSet() { + override fun clone(): B = throw AssertionError() +} + +fun box(): String { + return try { + B().clone() + "Fail 1" + } catch (e: AssertionError) { + try { + val hs: HashSet = B() + hs.clone() + "Fail 2" + } catch (e: AssertionError) { + "OK" + } + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/overrideAbstractProperty.kt b/backend.native/tests/external/codegen/blackbox/bridges/overrideAbstractProperty.kt new file mode 100644 index 00000000000..ec01cfced5c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/overrideAbstractProperty.kt @@ -0,0 +1,10 @@ +public abstract class AbstractClass { + public abstract val some: T +} + +public class Class: AbstractClass() { + public override val some: String + get() = "OK" +} + +fun box(): String = Class().some diff --git a/backend.native/tests/external/codegen/blackbox/bridges/overrideReturnType.kt b/backend.native/tests/external/codegen/blackbox/bridges/overrideReturnType.kt new file mode 100644 index 00000000000..e8d2619eb02 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/overrideReturnType.kt @@ -0,0 +1,13 @@ +open class C { + open fun f(): Any = "C f" +} + +class D() : C() { + override fun f(): String = "D f" +} + +fun box(): String{ + val d : C = D() + if(d.f() != "D f") return "fail f" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/propertyAccessorsWithoutBody.kt b/backend.native/tests/external/codegen/blackbox/bridges/propertyAccessorsWithoutBody.kt new file mode 100644 index 00000000000..82a9b0b930c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/propertyAccessorsWithoutBody.kt @@ -0,0 +1,15 @@ +open class A { + open var x: T = "Fail" as T + get +} + +class B : A() { + override var x: String = "Fail" + set +} + +fun box(): String { + val a: A = B() + a.x = "OK" + return a.x +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/propertyDiamond.kt b/backend.native/tests/external/codegen/blackbox/bridges/propertyDiamond.kt new file mode 100644 index 00000000000..802f6f77932 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/propertyDiamond.kt @@ -0,0 +1,18 @@ +interface A { + val o: O + val k: K +} + +interface B : A + +interface C : A + +class D : B, C { + override val o = "O" + override val k = "K" +} + +fun box(): String { + val a: A = D() + return a.o + a.k +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/propertyInConstructor.kt b/backend.native/tests/external/codegen/blackbox/bridges/propertyInConstructor.kt new file mode 100644 index 00000000000..9ca1e8bf8f5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/propertyInConstructor.kt @@ -0,0 +1,11 @@ +interface A { + var x: T +} + +class B(override var x: String) : A + +fun box(): String { + val a: A = B("Fail") + a.x = "OK" + return a.x +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/propertySetter.kt b/backend.native/tests/external/codegen/blackbox/bridges/propertySetter.kt new file mode 100644 index 00000000000..a258dc85346 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/propertySetter.kt @@ -0,0 +1,13 @@ +interface A { + var v: T +} + +class B : A { + override var v: String = "Fail" +} + +fun box(): String { + val a: A = B() + a.v = "OK" + return a.v +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/simple.kt b/backend.native/tests/external/codegen/blackbox/bridges/simple.kt new file mode 100644 index 00000000000..284d7cbb44c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/simple.kt @@ -0,0 +1,18 @@ +open class A { + open fun foo(t: T) = "A" +} + +class Z : A() { + override fun foo(t: String) = "Z" +} + + +fun box(): String { + val z = Z() + val a: A = z + return when { + z.foo("") != "Z" -> "Fail #1" + a.foo("") != "Z" -> "Fail #2" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/simpleEnum.kt b/backend.native/tests/external/codegen/blackbox/bridges/simpleEnum.kt new file mode 100644 index 00000000000..0446aba8c33 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/simpleEnum.kt @@ -0,0 +1,20 @@ +interface A { + open fun foo(t: T) = "A" +} + +enum class Z(val aname: String) : A { + Z1("Z1"), + Z2("Z2"); + override fun foo(t: String) = aname +} + + +fun box(): String { + return when { + Z.Z1.foo("") != "Z1" -> "Fail #1" + Z.Z2.foo("") != "Z2" -> "Fail #2" + (Z.Z1 as A).foo("") != "Z1" -> "Fail #3" + (Z.Z2 as A).foo("") != "Z2" -> "Fail #4" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/simpleGenericMethod.kt b/backend.native/tests/external/codegen/blackbox/bridges/simpleGenericMethod.kt new file mode 100644 index 00000000000..81e6c8607c1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/simpleGenericMethod.kt @@ -0,0 +1,18 @@ +open class A { + open fun foo(t: T, u: U) = "A" +} + +class Z : A() { + override fun foo(t: String, u: U) = "Z" +} + + +fun box(): String { + val z = Z() + val a: A = z + return when { + z.foo("", 0) != "Z" -> "Fail #1" + a.foo("", 0) != "Z" -> "Fail #2" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/simpleObject.kt b/backend.native/tests/external/codegen/blackbox/bridges/simpleObject.kt new file mode 100644 index 00000000000..5ff3c8177e6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/simpleObject.kt @@ -0,0 +1,23 @@ +open class A { + open fun foo(t: T) = "A" +} + +object Z : A() { + override fun foo(t: String) = "Z" +} + + +fun box(): String { + val z = object : A() { + override fun foo(t: String) = "z" + } + val az: A = Z + val a: A = z + return when { + Z.foo("") != "Z" -> "Fail #1" + z.foo("") != "z" -> "Fail #2" + az.foo("") != "Z" -> "Fail #3" + a.foo("") != "z" -> "Fail #4" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/simpleReturnType.kt b/backend.native/tests/external/codegen/blackbox/bridges/simpleReturnType.kt new file mode 100644 index 00000000000..ffd0bf84892 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/simpleReturnType.kt @@ -0,0 +1,17 @@ +open class A(val t: T) { + open fun foo(): T = t +} + +class Z : A(17) { + override fun foo() = 239 +} + +fun box(): String { + val z = Z() + val a: A = z + return when { + z.foo() != 239 -> "Fail #1" + a.foo() != 239 -> "Fail #2" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/simpleTraitImpl.kt b/backend.native/tests/external/codegen/blackbox/bridges/simpleTraitImpl.kt new file mode 100644 index 00000000000..1e1ccbab17e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/simpleTraitImpl.kt @@ -0,0 +1,16 @@ +interface A { + fun foo(t: T) = "A" +} + +class Z : A + + +fun box(): String { + val z = Z() + val a: A = z + return when { + z.foo("") != "A" -> "Fail #1" + a.foo("") != "A" -> "Fail #2" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/simpleUpperBound.kt b/backend.native/tests/external/codegen/blackbox/bridges/simpleUpperBound.kt new file mode 100644 index 00000000000..dea1f7eb647 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/simpleUpperBound.kt @@ -0,0 +1,18 @@ +open class A { + open fun foo(t: T) = "A" +} + +class Z : A() { + override fun foo(t: Int) = "Z" +} + + +fun box(): String { + val z = Z() + val a: A = z + return when { + z.foo(0) != "Z" -> "Fail #1" + a.foo(0) != "Z" -> "Fail #2" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/strListContains.kt b/backend.native/tests/external/codegen/blackbox/bridges/strListContains.kt new file mode 100644 index 00000000000..0d260822554 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/strListContains.kt @@ -0,0 +1,52 @@ +class StrList : List { + override val size: Int + get() = throw UnsupportedOperationException() + + override fun isEmpty(): Boolean { + throw UnsupportedOperationException() + } + + override fun contains(o: String?) = o == null || o == "abc" + + override fun iterator(): Iterator { + throw UnsupportedOperationException() + } + + override fun containsAll(c: Collection) = false + override fun get(index: Int): String { + throw UnsupportedOperationException() + } + + override fun indexOf(o: String?): Int { + throw UnsupportedOperationException() + } + + override fun lastIndexOf(o: String?): Int { + throw UnsupportedOperationException() + } + + override fun listIterator(): ListIterator { + throw UnsupportedOperationException() + } + + override fun listIterator(index: Int): ListIterator { + throw UnsupportedOperationException() + } + + override fun subList(fromIndex: Int, toIndex: Int): List { + throw UnsupportedOperationException() + } +} + +fun Collection.forceContains(x: Any?): Boolean = contains(x as E) + +fun box(): String { + val strList = StrList() + + if (strList.forceContains(1)) return "fail 1" + if (!strList.forceContains(null)) return "fail 2" + if (strList.forceContains("cde")) return "fail 3" + if (!strList.forceContains("abc")) return "fail 4" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/abstractFun.kt b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/abstractFun.kt new file mode 100644 index 00000000000..39e1b1935f0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/abstractFun.kt @@ -0,0 +1,22 @@ +abstract class A { + abstract fun foo(t: T): String +} + +abstract class B : A() + +class Z : B() { + override fun foo(t: String) = "Z" +} + + +fun box(): String { + val z = Z() + val b: B = z + val a: A = z + return when { + z.foo("") != "Z" -> "Fail #1" + b.foo("") != "Z" -> "Fail #2" + a.foo("") != "Z" -> "Fail #3" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/boundedTypeArguments.kt b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/boundedTypeArguments.kt new file mode 100644 index 00000000000..3db4852ed2b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/boundedTypeArguments.kt @@ -0,0 +1,21 @@ +open class A { + open fun foo(t: T, u: U) = "A" +} + +open class B : A() + +class Z : B() { + override fun foo(t: Int, u: Number) = "Z" +} + +fun box(): String { + val z = Z() + val b: B = z + val a: A = z + return when { + z.foo(0, 0) != "Z" -> "Fail #1" + b.foo(0, 0) != "Z" -> "Fail #2" + a.foo(0, 0) != "Z" -> "Fail #3" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/delegation.kt b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/delegation.kt new file mode 100644 index 00000000000..3d80f6523ea --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/delegation.kt @@ -0,0 +1,18 @@ +interface A { + fun id(t: T): T +} + +open class B : A { + override fun id(t: String) = t +} + +class C : B() + +class D : A by C() + +fun box(): String { + val d = D() + if (d.id("") != "") return "Fail" + val a: A = d + return a.id("OK") +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/differentErasureInSuperClass.kt b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/differentErasureInSuperClass.kt new file mode 100644 index 00000000000..d3bb7ce59e7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/differentErasureInSuperClass.kt @@ -0,0 +1,15 @@ +public open class A { + fun foo(x: T) = "O" + fun foo(x: A) = "K" +} + +// Shoudt not be reported CONFLICTING_INHERITED_JVM_DECLARATIONS +class B : A>() + +fun box(): String { + val x: A = A() + val y: A> = A() + val b = B() + + return b.foo(x) + b.foo(y) +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/differentErasureInSuperClassComplex.kt b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/differentErasureInSuperClassComplex.kt new file mode 100644 index 00000000000..473cee266e1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/differentErasureInSuperClassComplex.kt @@ -0,0 +1,35 @@ +public open class A { + fun foo(x: T) = "O" + fun foo(x: A) = "K" +} + +interface C { + fun foo(x: E): String + fun foo(x: A): String +} + +interface D { + fun foo(x: A>): String +} + +// Shoudt not be reported CONFLICTING_INHERITED_JVM_DECLARATIONS +class B : A>(), C>, D + +fun box(): String { + val x: A = A() + val y: A> = A() + + val b = B() + val bResult = b.foo(x) + b.foo(y) + if (bResult != "OK") return "fail 1: $bResult" + + val c: C> = B() + val cResult = c.foo(x) + c.foo(y) + if (cResult != "OK") return "fail 2: $cResult" + + val d: D = B() + + if (d.foo(y) != "K") return "fail 3" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/enum.kt b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/enum.kt new file mode 100644 index 00000000000..243498038e6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/enum.kt @@ -0,0 +1,28 @@ +interface A { + open fun foo(t: T) = "A" +} + +interface B : A + +enum class Z(val aname: String) : B { + Z1("Z1"), + Z2("Z2"); + override fun foo(t: String) = aname +} + + +fun box(): String { + val z1b: B = Z.Z1 + val z2b: B = Z.Z2 + val z1a: A = Z.Z1 + val z2a: A = Z.Z2 + return when { + Z.Z1.foo("") != "Z1" -> "Fail #1" + Z.Z2.foo("") != "Z2" -> "Fail #2" + z1b.foo("") != "Z1" -> "Fail #3" + z2b.foo("") != "Z2" -> "Fail #4" + z1a.foo("") != "Z1" -> "Fail #5" + z2a.foo("") != "Z2" -> "Fail #6" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/genericMethod.kt b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/genericMethod.kt new file mode 100644 index 00000000000..0119eba58a8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/genericMethod.kt @@ -0,0 +1,22 @@ +open class A { + open fun foo(t: T, u: U) = "A" +} + +open class B : A() + +class Z : B() { + override fun foo(t: String, u: U) = "Z" +} + + +fun box(): String { + val z = Z() + val b: B = z + val a: A = z + return when { + z.foo("", 0) != "Z" -> "Fail #1" + b.foo("", 0) != "Z" -> "Fail #2" + a.foo("", 0) != "Z" -> "Fail #3" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/object.kt b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/object.kt new file mode 100644 index 00000000000..c7c95464c59 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/object.kt @@ -0,0 +1,30 @@ +open class A { + open fun foo(t: T) = "A" +} + +open class B : A() + +object Z : B() { + override fun foo(t: String) = "Z" +} + + +fun box(): String { + val o = object : B() { + override fun foo(t: String) = "o" + } + val zb: B = Z + val ob: B = o + val za: A = Z + val oa: A = o + + return when { + Z.foo("") != "Z" -> "Fail #1" + o.foo("") != "o" -> "Fail #2" + zb.foo("") != "Z" -> "Fail #3" + ob.foo("") != "o" -> "Fail #4" + za.foo("") != "Z" -> "Fail #5" + oa.foo("") != "o" -> "Fail #6" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/property.kt b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/property.kt new file mode 100644 index 00000000000..21208405891 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/property.kt @@ -0,0 +1,15 @@ +open class A(val t: T) { + open val foo: T = t +} + +open class B : A("Fail") + +class Z : B() { + override val foo = "OK" +} + + +fun box(): String { + val a: A = Z() + return a.foo +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/simple.kt b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/simple.kt new file mode 100644 index 00000000000..c6c2637ef22 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/simple.kt @@ -0,0 +1,22 @@ +open class A { + open fun foo(t: T) = "A" +} + +open class B : A() + +class Z : B() { + override fun foo(t: String) = "Z" +} + + +fun box(): String { + val z = Z() + val b: B = z + val a: A = z + return when { + z.foo("") != "Z" -> "Fail #1" + b.foo("") != "Z" -> "Fail #2" + a.foo("") != "Z" -> "Fail #3" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/upperBound.kt b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/upperBound.kt new file mode 100644 index 00000000000..f6d4dccfc40 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/substitutionInSuperClass/upperBound.kt @@ -0,0 +1,22 @@ +open class A { + open fun foo(t: T) = "A" +} + +open class B : A() + +class Z : B() { + override fun foo(t: Int) = "Z" +} + + +fun box(): String { + val z = Z() + val b: B = z + val a: A = z + return when { + z.foo(0) != "Z" -> "Fail #1" + b.foo(0) != "Z" -> "Fail #2" + a.foo(0) != "Z" -> "Fail #3" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/traitImplInheritsTraitImpl.kt b/backend.native/tests/external/codegen/blackbox/bridges/traitImplInheritsTraitImpl.kt new file mode 100644 index 00000000000..ec0cf44081a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/traitImplInheritsTraitImpl.kt @@ -0,0 +1,17 @@ +interface A { + fun foo(): Any = "A" +} + +interface B : A { + override fun foo(): String = "B" +} + +class C : B + +fun box(): String { + val c = C() + val b: B = c + val a: A = c + var r = c.foo() + b.foo() + a.foo() + return if (r == "BBB") "OK" else "Fail: $r" +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/twoParentsWithDifferentMethodsTwoBridges.kt b/backend.native/tests/external/codegen/blackbox/bridges/twoParentsWithDifferentMethodsTwoBridges.kt new file mode 100644 index 00000000000..38d7cb2431f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/twoParentsWithDifferentMethodsTwoBridges.kt @@ -0,0 +1,33 @@ +interface A { + fun foo(t: T, u: Int) = "A" +} + +interface B { + fun foo(t: T, u: U) = "B" +} + +class Z1 : A, B { + override fun foo(t: String, u: Int) = "Z1" +} + +class Z2 : B, A { + override fun foo(t: String, u: Int) = "Z2" +} + +fun box(): String { + val z1 = Z1() + val z2 = Z2() + val z1a: A = z1 + val z1b: B = z1 + val z2a: A = z2 + val z2b: B = z2 + return when { + z1.foo("", 0) != "Z1" -> "Fail #1" + z1a.foo("", 0) != "Z1" -> "Fail #2" + z1b.foo("", 0) != "Z1" -> "Fail #3" + z2.foo("", 0) != "Z2" -> "Fail #4" + z2a.foo("", 0) != "Z2" -> "Fail #5" + z2b.foo("", 0) != "Z2" -> "Fail #6" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/twoParentsWithDifferentMethodsTwoBridges2.kt b/backend.native/tests/external/codegen/blackbox/bridges/twoParentsWithDifferentMethodsTwoBridges2.kt new file mode 100644 index 00000000000..07af5afaa4e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/twoParentsWithDifferentMethodsTwoBridges2.kt @@ -0,0 +1,40 @@ +interface A { + fun foo(t: T, u: Int) = "A" +} + +interface B { + fun foo(t: T, u: U) = "B" +} + +interface Z1 : A, B { + override fun foo(t: String, u: Int) = "Z1" +} + +interface Z2 : B, A { + override fun foo(t: String, u: Int) = "Z2" +} + + +class Z1Class : Z1 { +} + +class Z2Class : Z2 { +} + +fun box(): String { + val z1 = Z1Class() + val z2 = Z2Class() + val z1a: A = z1 + val z1b: B = z1 + val z2a: A = z2 + val z2b: B = z2 + return when { + z1.foo("", 0) != "Z1" -> "Fail #1" + z1a.foo("", 0) != "Z1" -> "Fail #2" + z1b.foo("", 0) != "Z1" -> "Fail #3" //FAIL + z2.foo("", 0) != "Z2" -> "Fail #4" + z2a.foo("", 0) != "Z2" -> "Fail #5" + z2b.foo("", 0) != "Z2" -> "Fail #6" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/bridges/twoParentsWithTheSameMethodOneBridge.kt b/backend.native/tests/external/codegen/blackbox/bridges/twoParentsWithTheSameMethodOneBridge.kt new file mode 100644 index 00000000000..de57467d8b1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/bridges/twoParentsWithTheSameMethodOneBridge.kt @@ -0,0 +1,24 @@ +interface A { + fun foo(t: T) = "A" +} + +interface B { + fun foo(t: T) = "B" +} + +class Z : A, B { + override fun foo(t: Int) = "Z" +} + + +fun box(): String { + val z = Z() + val a: A = z + val b: B = z + return when { + z.foo(0) != "Z" -> "Fail #1" + a.foo(0) != "Z" -> "Fail #2" + b.foo(0) != "Z" -> "Fail #3" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/Collection.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/Collection.kt new file mode 100644 index 00000000000..26a74d507bc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/Collection.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class MyCollection: Collection { + override val size: Int get() = 0 + override fun isEmpty(): Boolean = true + override fun contains(o: T): Boolean = false + override fun iterator(): Iterator = throw UnsupportedOperationException() + override fun containsAll(c: Collection): Boolean = false + override fun hashCode(): Int = 0 + override fun equals(other: Any?): Boolean = false +} + +fun expectUoe(block: () -> Any) { + try { + block() + throw AssertionError() + } catch (e: UnsupportedOperationException) { + } +} + +fun box(): String { + val myCollection = MyCollection() + val collection = myCollection as java.util.Collection + + expectUoe { collection.add("") } + expectUoe { collection.remove("") } + expectUoe { collection.addAll(myCollection) } + expectUoe { collection.removeAll(myCollection) } + expectUoe { collection.retainAll(myCollection) } + expectUoe { collection.clear() } + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/Iterator.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/Iterator.kt new file mode 100644 index 00000000000..ad0fc09d46c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/Iterator.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class MyIterator(val v: T): Iterator { + override fun next(): T = v + override fun hasNext(): Boolean = true +} + +fun box(): String { + try { + (MyIterator("") as java.util.Iterator).remove() + throw AssertionError() + } catch (e: UnsupportedOperationException) { + return "OK" + } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/IteratorWithRemove.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/IteratorWithRemove.kt new file mode 100644 index 00000000000..5958c38ca05 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/IteratorWithRemove.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class MyIterator(val v: T): Iterator { + override fun next(): T = v + override fun hasNext(): Boolean = true + + public fun remove() {} +} + +fun box(): String { + (MyIterator("") as java.util.Iterator).remove() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/List.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/List.kt new file mode 100644 index 00000000000..7674d221a35 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/List.kt @@ -0,0 +1,42 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class MyList: List { + override val size: Int get() = 0 + override fun isEmpty(): Boolean = true + override fun contains(o: T): Boolean = false + override fun iterator(): Iterator = throw Error() + override fun containsAll(c: Collection): Boolean = false + override fun get(index: Int): T = throw IndexOutOfBoundsException() + override fun indexOf(o: T): Int = -1 + override fun lastIndexOf(o: T): Int = -1 + override fun listIterator(): ListIterator = throw Error() + override fun listIterator(index: Int): ListIterator = throw Error() + override fun subList(fromIndex: Int, toIndex: Int): List = this + override fun hashCode(): Int = 0 + override fun equals(other: Any?): Boolean = false +} + +fun expectUoe(block: () -> Any) { + try { + block() + throw AssertionError() + } catch (e: UnsupportedOperationException) { + } +} + +fun box(): String { + val list = MyList() as java.util.List + + expectUoe { list.add("") } + expectUoe { list.remove("") } + expectUoe { list.addAll(list) } + expectUoe { list.removeAll(list) } + expectUoe { list.retainAll(list) } + expectUoe { list.clear() } + expectUoe { list.set(0, "") } + expectUoe { list.add(0, "") } + expectUoe { list.remove(0) } + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/ListIterator.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/ListIterator.kt new file mode 100644 index 00000000000..d5a829d7566 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/ListIterator.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class MyListIterator : ListIterator { + override fun next(): T = null!! + override fun hasNext(): Boolean = null!! + override fun hasPrevious(): Boolean = null!! + override fun previous(): T = null!! + override fun nextIndex(): Int = null!! + override fun previousIndex(): Int = null!! +} + +fun expectUoe(block: () -> Any) { + try { + block() + throw AssertionError() + } catch (e: UnsupportedOperationException) { + } +} + +fun box(): String { + val list = MyListIterator() as java.util.ListIterator + + expectUoe { list.set("") } + expectUoe { list.add("") } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/ListWithAllImplementations.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/ListWithAllImplementations.kt new file mode 100644 index 00000000000..9b6a2d02310 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/ListWithAllImplementations.kt @@ -0,0 +1,45 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class MyList(val v: T): List { + override val size: Int get() = 0 + override fun isEmpty(): Boolean = true + override fun contains(o: T): Boolean = false + override fun iterator(): Iterator = throw Error() + override fun containsAll(c: Collection): Boolean = false + override fun get(index: Int): T = v + override fun indexOf(o: T): Int = -1 + override fun lastIndexOf(o: T): Int = -1 + override fun listIterator(): ListIterator = throw Error() + override fun listIterator(index: Int): ListIterator = throw Error() + override fun subList(fromIndex: Int, toIndex: Int): List = throw Error() + override fun hashCode(): Int = 0 + override fun equals(other: Any?): Boolean = false + + public fun add(e: T): Boolean = true + public fun remove(o: T): Boolean = true + public fun addAll(c: Collection): Boolean = true + public fun addAll(index: Int, c: Collection): Boolean = true + public fun removeAll(c: Collection): Boolean = true + public fun retainAll(c: Collection): Boolean = true + public fun clear() {} + public fun set(index: Int, element: T): T = element + public fun add(index: Int, element: T) {} + public fun removeAt(index: Int): T = v +} + +fun box(): String { + val list = MyList("") as java.util.List + + list.add("") + list.remove("") + list.addAll(list) + list.removeAll(list) + list.retainAll(list) + list.clear() + list.set(0, "") + list.add(0, "") + list.remove(0) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/ListWithAllInheritedImplementations.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/ListWithAllInheritedImplementations.kt new file mode 100644 index 00000000000..0931a43f501 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/ListWithAllInheritedImplementations.kt @@ -0,0 +1,47 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +open class Super(val v: T) { + public fun add(e: T): Boolean = true + public fun remove(o: T): Boolean = true + public fun addAll(c: Collection): Boolean = true + public fun addAll(index: Int, c: Collection): Boolean = true + public fun removeAll(c: Collection): Boolean = true + public fun retainAll(c: Collection): Boolean = true + public fun clear() {} + public fun set(index: Int, element: T): T = element + public fun add(index: Int, element: T) {} + public fun removeAt(index: Int): T = v +} + +class MyList(v: T): Super(v), List { + override val size: Int get() = 0 + override fun isEmpty(): Boolean = true + override fun contains(o: T): Boolean = false + override fun iterator(): Iterator = throw Error() + override fun containsAll(c: Collection): Boolean = false + override fun get(index: Int): T = v + override fun indexOf(o: T): Int = -1 + override fun lastIndexOf(o: T): Int = -1 + override fun listIterator(): ListIterator = throw Error() + override fun listIterator(index: Int): ListIterator = throw Error() + override fun subList(fromIndex: Int, toIndex: Int): List = throw Error() + override fun hashCode(): Int = 0 + override fun equals(other: Any?): Boolean = false +} + +fun box(): String { + val list = MyList("") as java.util.List + + list.add("") + list.remove("") + list.addAll(list) + list.removeAll(list) + list.retainAll(list) + list.clear() + list.set(0, "") + list.add(0, "") + list.remove(0) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/Map.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/Map.kt new file mode 100644 index 00000000000..c8438bb3d13 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/Map.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class MyMap: Map { + override val size: Int get() = 0 + override fun isEmpty(): Boolean = true + override fun containsKey(key: K): Boolean = false + override fun containsValue(value: V): Boolean = false + override fun get(key: K): V? = null + override val keys: Set get() = throw UnsupportedOperationException() + override val values: Collection get() = throw UnsupportedOperationException() + override val entries: Set> get() = throw UnsupportedOperationException() +} + +fun expectUoe(block: () -> Unit) { + try { + block() + throw AssertionError() + } catch (e: UnsupportedOperationException) { + } +} + +fun box(): String { + val myMap = MyMap() + val map = myMap as java.util.Map + + expectUoe { map.put("", 1) } + expectUoe { map.remove("") } + expectUoe { map.putAll(myMap) } + expectUoe { map.clear() } + + return "OK" +} + diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/MapEntry.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/MapEntry.kt new file mode 100644 index 00000000000..33a83a55ec8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/MapEntry.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class MyMapEntry: Map.Entry { + override fun hashCode(): Int = 0 + override fun equals(other: Any?): Boolean = false + override val key: K get() = throw UnsupportedOperationException() + override val value: V get() = throw UnsupportedOperationException() +} + +fun box(): String { + try { + (MyMapEntry() as java.util.Map.Entry).setValue(1) + throw AssertionError() + } catch (e: UnsupportedOperationException) { + return "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/MapEntryWithSetValue.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/MapEntryWithSetValue.kt new file mode 100644 index 00000000000..ce8eaaf6886 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/MapEntryWithSetValue.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class MyMapEntry: Map.Entry { + override fun hashCode(): Int = 0 + override fun equals(other: Any?): Boolean = false + override val key: K get() = throw UnsupportedOperationException() + override val value: V get() = throw UnsupportedOperationException() + + public fun setValue(value: V): V = value +} + +fun box(): String { + (MyMapEntry() as java.util.Map.Entry).setValue(1) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/MapWithAllImplementations.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/MapWithAllImplementations.kt new file mode 100644 index 00000000000..d84d89369d3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/MapWithAllImplementations.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class MyMap: Map { + override val size: Int get() = 0 + override fun isEmpty(): Boolean = true + override fun containsKey(key: K): Boolean = false + override fun containsValue(value: V): Boolean = false + override fun get(key: K): V? = null + override val keys: Set get() = throw UnsupportedOperationException() + override val values: Collection get() = throw UnsupportedOperationException() + override val entries: Set> get() = throw UnsupportedOperationException() + + public fun put(key: K, value: V): V? = null + public fun remove(key: K): V? = null + public fun putAll(m: Map) {} + public fun clear() {} +} + +fun box(): String { + val myMap = MyMap() + val map = myMap as java.util.Map + + map.put("", 1) + map.remove("") + map.putAll(myMap) + map.clear() + + return "OK" +} + diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/SubstitutedList.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/SubstitutedList.kt new file mode 100644 index 00000000000..6656b7d769b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/SubstitutedList.kt @@ -0,0 +1,42 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class MyList: List { + override val size: Int get() = 0 + override fun isEmpty(): Boolean = true + override fun contains(o: String): Boolean = false + override fun iterator(): Iterator = throw Error() + override fun containsAll(c: Collection): Boolean = false + override fun get(index: Int): String = throw IndexOutOfBoundsException() + override fun indexOf(o: String): Int = -1 + override fun lastIndexOf(o: String): Int = -1 + override fun listIterator(): ListIterator = throw Error() + override fun listIterator(index: Int): ListIterator = throw Error() + override fun subList(fromIndex: Int, toIndex: Int): List = this + override fun hashCode(): Int = 0 + override fun equals(other: Any?): Boolean = false +} + +fun expectUoe(block: () -> Any) { + try { + block() + throw AssertionError() + } catch (e: UnsupportedOperationException) { + } +} + +fun box(): String { + val list = MyList() as java.util.List + + expectUoe { list.add("") } + expectUoe { list.remove("") } + expectUoe { list.addAll(list) } + expectUoe { list.removeAll(list) } + expectUoe { list.retainAll(list) } + expectUoe { list.clear() } + expectUoe { list.set(0, "") } + expectUoe { list.add(0, "") } + expectUoe { list.remove(0) } + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/abstractMember.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/abstractMember.kt new file mode 100644 index 00000000000..100748198dc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/abstractMember.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +abstract class A : Iterator { + abstract fun remove(): Unit +} + +class B(var result: String) : A() { + override fun next() = "" + override fun hasNext() = false + override fun remove() { + result = "OK" + } +} + +fun box(): String { + val a = B("Fail") as java.util.Iterator + a.next() + a.hasNext() + a.remove() + + return (a as B).result +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/customReadOnlyIterator.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/customReadOnlyIterator.kt new file mode 100644 index 00000000000..2038e67cbb5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/customReadOnlyIterator.kt @@ -0,0 +1,34 @@ +class A : Collection { + override val size: Int + get() = throw UnsupportedOperationException() + + override fun contains(element: Char): Boolean { + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun containsAll(elements: Collection): Boolean { + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun isEmpty(): Boolean { + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun iterator() = MyIterator +} + +object MyIterator : Iterator { + override fun hasNext() = true + + override fun next() = 'a' +} + + +fun box(): String { + val it: MyIterator = A().iterator() + + if (!it.hasNext()) return "fail 1" + if (it.next() != 'a') return "fail 2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/delegationToArrayList.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/delegationToArrayList.kt new file mode 100644 index 00000000000..b9436fab469 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/delegationToArrayList.kt @@ -0,0 +1,49 @@ +// TARGET_BACKEND: JVM + +import java.util.ArrayList + +class A : List by ArrayList() + +class B : List by A() + +fun expectUoe(block: () -> Any) { + try { + block() + throw AssertionError() + } catch (e: UnsupportedOperationException) { + } +} + +fun box(): String { + val a = A() as java.util.List + expectUoe { a.add("") } + expectUoe { a.remove("") } + expectUoe { a.addAll(a) } + expectUoe { a.addAll(0, a) } + expectUoe { a.removeAll(a) } + expectUoe { a.retainAll(a) } + expectUoe { a.clear() } + expectUoe { a.add(0, "") } + expectUoe { a.set(0, "") } + expectUoe { a.remove(0) } + a.listIterator() + a.listIterator(0) + a.subList(0, 0) + + val b = B() as java.util.List + expectUoe { b.add("") } + expectUoe { b.remove("") } + expectUoe { b.addAll(b) } + expectUoe { b.addAll(0, b) } + expectUoe { b.removeAll(b) } + expectUoe { b.retainAll(b) } + expectUoe { b.clear() } + expectUoe { b.add(0, "") } + expectUoe { b.set(0, "") } + expectUoe { b.remove(0) } + b.listIterator() + b.listIterator(0) + b.subList(0, 0) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/abstractList.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/abstractList.kt new file mode 100644 index 00000000000..ba7fdde2891 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/abstractList.kt @@ -0,0 +1,22 @@ +// TARGET_BACKEND: JVM + +import java.util.AbstractList + +class A : AbstractList() { + override fun get(index: Int): String = "" + override val size: Int get() = 0 +} + +fun box(): String { + val a = A() + val b = A() + + a.addAll(b) + a.addAll(0, b) + a.removeAll(b) + a.retainAll(b) + a.clear() + a.remove("") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/abstractMap.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/abstractMap.kt new file mode 100644 index 00000000000..c8bb76a50ba --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/abstractMap.kt @@ -0,0 +1,24 @@ +// TARGET_BACKEND: JVM + +import java.util.AbstractMap +import java.util.Collections + +class A : AbstractMap() { + override val entries: MutableSet> get() = Collections.emptySet() +} + +fun box(): String { + val a = A() + val b = A() + + a.remove(0) + + a.putAll(b) + a.clear() + + a.keys + a.values + a.entries + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/abstractSet.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/abstractSet.kt new file mode 100644 index 00000000000..bb2b1ec5b0a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/abstractSet.kt @@ -0,0 +1,18 @@ +class A : HashSet() + +fun box(): String { + val a = A() + val b = A() + + a.iterator() + + a.add(0L) + a.remove(0L) + + a.addAll(b) + a.removeAll(b) + a.retainAll(b) + a.clear() + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/arrayList.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/arrayList.kt new file mode 100644 index 00000000000..9a18322f4a8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/arrayList.kt @@ -0,0 +1,22 @@ +// KT-6042 java.lang.UnsupportedOperationException with ArrayList + +class A : ArrayList() + +fun box(): String { + val a = A() + val b = A() + + a.addAll(b) + a.addAll(0, b) + a.removeAll(b) + a.retainAll(b) + a.clear() + + a.add("") + a.set(0, "") + a.add(0, "") + a.removeAt(0) + a.remove("") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/hashMap.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/hashMap.kt new file mode 100644 index 00000000000..2c63371c63c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/hashMap.kt @@ -0,0 +1,18 @@ +class A : HashMap() + +fun box(): String { + val a = A() + val b = A() + + a.put("", 0.0) + a.remove("") + + a.putAll(b) + a.clear() + + a.keys + a.values + a.entries + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/hashSet.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/hashSet.kt new file mode 100644 index 00000000000..bb2b1ec5b0a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/hashSet.kt @@ -0,0 +1,18 @@ +class A : HashSet() + +fun box(): String { + val a = A() + val b = A() + + a.iterator() + + a.add(0L) + a.remove(0L) + + a.addAll(b) + a.removeAll(b) + a.retainAll(b) + a.clear() + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/mapEntry.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/mapEntry.kt new file mode 100644 index 00000000000..85ebbd34f5b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/extendJavaCollections/mapEntry.kt @@ -0,0 +1,30 @@ +// TARGET_BACKEND: JVM + +// FILE: Test.java + +import java.lang.*; +import java.util.*; + +public class Test { + public static class MapEntryImpl implements Map.Entry { + public String getKey() { return null; } + public String getValue() { return null; } + public String setValue(String s) { return null; } + } +} + +// FILE: main.kt + +//class MyIterable : Test.IterableImpl() +//class MyIterator : Test.IteratorImpl() +class MyMapEntry : Test.MapEntryImpl() + +fun box(): String { + + val b = MyMapEntry() + b.key + b.value + b.setValue(null) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/immutableRemove.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/immutableRemove.kt new file mode 100644 index 00000000000..2710f121246 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/immutableRemove.kt @@ -0,0 +1,53 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FULL_JDK +// WITH_RUNTIME +interface ImmutableCollection : Collection { + fun add(element: @UnsafeVariance E): ImmutableCollection + fun addAll(elements: Collection<@UnsafeVariance E>): ImmutableCollection + fun remove(element: @UnsafeVariance E): ImmutableCollection +} + +class ImmutableCollectionmpl : ImmutableCollection { + override val size: Int + get() = throw UnsupportedOperationException() + + override fun contains(element: E): Boolean { + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun containsAll(elements: Collection): Boolean { + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun isEmpty(): Boolean { + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun iterator(): Iterator { + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun add(element: E): ImmutableCollection = this + override fun addAll(elements: Collection): ImmutableCollection = this + override fun remove(element: E): ImmutableCollection = this +} + +fun box(): String { + val c = ImmutableCollectionmpl() + if (c.remove("") !== c) return "fail 1" + if (c.add("") !== c) return "fail 2" + if (c.addAll(java.util.ArrayList()) !== c) return "fail 3" + + val method = c.javaClass.methods.single { it.name == "remove" && it.returnType == Boolean::class.javaPrimitiveType } + + try { + method.invoke(c, "") + return "fail 4" + } catch (e: java.lang.reflect.InvocationTargetException) { + if (e.cause!!.message != "Operation is not supported for read-only collection") return "fail 5: ${e.cause!!.message}" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/implementationInTrait.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/implementationInTrait.kt new file mode 100644 index 00000000000..b82febc0667 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/implementationInTrait.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +interface Addable { + fun add(s: String): Boolean = true +} + +class C : Addable, List { + override val size: Int get() = null!! + override fun isEmpty(): Boolean = null!! + override fun contains(o: String): Boolean = null!! + override fun iterator(): Iterator = null!! + override fun containsAll(c: Collection): Boolean = null!! + override fun get(index: Int): String = null!! + override fun indexOf(o: String): Int = null!! + override fun lastIndexOf(o: String): Int = null!! + override fun listIterator(): ListIterator = null!! + override fun listIterator(index: Int): ListIterator = null!! + override fun subList(fromIndex: Int, toIndex: Int): List = null!! +} + +fun box(): String { + try { + val a = C() + if (!a.add("")) return "Fail 1" + if (!(a as Addable).add("")) return "Fail 2" + if (!(a as java.util.List).add("")) return "Fail 3" + return "OK" + } catch (e: UnsupportedOperationException) { + return "Fail: no stub method should be generated" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/inheritedImplementations.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/inheritedImplementations.kt new file mode 100644 index 00000000000..606144d696d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/inheritedImplementations.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +open class SetStringImpl { + fun add(s: String): Boolean = false + fun remove(o: String): Boolean = false + fun clear(): Unit {} +} + +class S : Set, SetStringImpl() { + override val size: Int get() = 0 + override fun isEmpty(): Boolean = true + override fun contains(o: String): Boolean = false + override fun iterator(): Iterator = null!! + override fun containsAll(c: Collection) = false +} + +fun box(): String { + val s = S() as java.util.Set + s.add("") + s.remove("") + s.clear() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/manyTypeParametersWithUpperBounds.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/manyTypeParametersWithUpperBounds.kt new file mode 100644 index 00000000000..f906f817cce --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/manyTypeParametersWithUpperBounds.kt @@ -0,0 +1,33 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME + +class A : Set { + override val size: Int get() = 0 + override fun isEmpty(): Boolean = true + override fun contains(o: W): Boolean = false + override fun iterator(): Iterator = emptySet().iterator() + override fun containsAll(c: Collection): Boolean = c.isEmpty() +} + +fun expectUoe(block: () -> Any) { + try { + block() + throw AssertionError() + } catch (e: UnsupportedOperationException) { + } +} + +fun box(): String { + val a = A() as java.util.Set + + a.iterator() + + expectUoe { a.add(42) } + expectUoe { a.remove(42) } + expectUoe { a.addAll(a) } + expectUoe { a.removeAll(a) } + expectUoe { a.retainAll(a) } + expectUoe { a.clear() } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/nonTrivialSubstitution.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/nonTrivialSubstitution.kt new file mode 100644 index 00000000000..d7671b38bd2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/nonTrivialSubstitution.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class MyCollection : Collection>> { + override fun iterator() = null!! + override val size: Int get() = null!! + override fun isEmpty(): Boolean = null!! + override fun contains(o: List>): Boolean = null!! + override fun containsAll(c: Collection>>): Boolean = null!! +} + +fun box(): String { + val c = MyCollection() as java.util.Collection>> + try { + c.add(ArrayList()) + return "Fail" + } catch (e: UnsupportedOperationException) { + return "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/nonTrivialUpperBound.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/nonTrivialUpperBound.kt new file mode 100644 index 00000000000..71c6e0e60b7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/nonTrivialUpperBound.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class MyIterator : Iterator { + override fun next() = null!! + override fun hasNext() = null!! +} + +fun box(): String { + try { + (MyIterator() as java.util.Iterator).remove() + return "Fail" + } catch (e: UnsupportedOperationException) { + return "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/substitutedIterable.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/substitutedIterable.kt new file mode 100644 index 00000000000..460328ffe0f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/substitutedIterable.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: Test.java + +public class Test { + public static void checkCallFromJava() { + try { + String x = TestKt.foo().iterator().next(); + throw new AssertionError("E should have been thrown"); + } catch (E e) { } + } +} + +// FILE: test.kt + +interface MyIterable : Iterable + +class E : RuntimeException() +fun foo(): MyIterable = throw E() + +fun box(): String { + try { + foo().iterator().next() + return "Fail: E should have been thrown" + } catch (e: E) {} + + Test.checkCallFromJava() + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/builtinStubMethods/substitutedListWithExtraSuperInterface.kt b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/substitutedListWithExtraSuperInterface.kt new file mode 100644 index 00000000000..e34741934e7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/builtinStubMethods/substitutedListWithExtraSuperInterface.kt @@ -0,0 +1,42 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: Test.java + +class Test { + interface A { + boolean add(String s); + } + + static class D extends C {} + + void test() { + A a = new D(); + a.add("lol"); + } +} + +// FILE: test.kt + +abstract class C : Test.A, List { + override val size: Int get() = null!! + override fun isEmpty(): Boolean = null!! + override fun contains(o: String): Boolean = null!! + override fun iterator(): Iterator = null!! + override fun containsAll(c: Collection): Boolean = null!! + override fun get(index: Int): String = null!! + override fun indexOf(o: String): Int = null!! + override fun lastIndexOf(o: String): Int = null!! + override fun listIterator(): ListIterator = null!! + override fun listIterator(index: Int): ListIterator = null!! + override fun subList(fromIndex: Int, toIndex: Int): List = null!! +} + +fun box(): String { + try { + Test().test() + return "Fail" + } catch (e: UnsupportedOperationException) { + return "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/array.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/array.kt new file mode 100644 index 00000000000..2a78bb9cc88 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/array.kt @@ -0,0 +1,11 @@ +open class A { + var f: String = "OK" +} + +class B : A() { +} + +fun box() : String { + val b = B() + return (b::f).get() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/companionObjectReceiver.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/companionObjectReceiver.kt new file mode 100644 index 00000000000..ddf856c54da --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/companionObjectReceiver.kt @@ -0,0 +1,7 @@ +class A { + companion object { + fun ok() = "OK" + } +} + +fun box() = (A.Companion::ok)() \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/enumEntryMember.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/enumEntryMember.kt new file mode 100644 index 00000000000..b62135e87bb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/enumEntryMember.kt @@ -0,0 +1,17 @@ +// IGNORE_BACKEND: JS, NATIVE +enum class E { + A, B; + + fun foo() = this.name +} + +fun box(): String { + val f = E.A::foo + val ef = E::foo + + if (f() != "A") return "Fail 1: ${f()}" + if (f == E.B::foo) return "Fail 2" + if (ef != E::foo) return "Fail 3" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/equals/nullableReceiverInEquals.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/equals/nullableReceiverInEquals.kt new file mode 100644 index 00000000000..1ecf9a29e7e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/equals/nullableReceiverInEquals.kt @@ -0,0 +1,37 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// See https://youtrack.jetbrains.com/issue/KT-14938 +// WITH_REFLECT + +class A + +val a = A() +val aa = A() + +fun A?.foo() {} + +var A?.bar: Int + get() = 42 + set(value) {} + +val aFoo = a::foo +val A_foo = A::foo +val nullFoo = null::foo + +val aBar = a::bar +val A_bar = A::bar +val nullBar = null::bar + +fun box(): String = + when { + nullFoo != null::foo -> "Bound extension refs with same receiver SHOULD be equal" + nullFoo == aFoo -> "Bound extension refs with different receivers SHOULD NOT be equal" + nullFoo == A_foo -> "Bound extension ref with receiver 'null' SHOULD NOT be equal to free ref" + + nullBar != null::bar -> "Bound extension property refs with same receiver SHOULD be equal" + nullBar == aBar -> "Bound extension property refs with different receivers SHOULD NOT be equal" + nullBar == A_bar -> "Bound extension property ref with receiver 'null' SHOULD NOT be equal to free property ref" + + else -> "OK" + } \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/equals/propertyAccessors.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/equals/propertyAccessors.kt new file mode 100644 index 00000000000..46848672257 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/equals/propertyAccessors.kt @@ -0,0 +1,32 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* + +class C { + var prop = 42 +} + +val C_propReflect = C::class.memberProperties.find { it.name == "prop" } as? KMutableProperty1 ?: throw AssertionError() +val C_prop = C::prop +val cProp = C()::prop + +fun box() = + when { + C_prop.getter != C_prop.getter -> "C_prop.getter != C_prop.getter" + C_propReflect.getter != C_propReflect.getter -> "C_propReflect.getter != C_propReflect.getter" + cProp.getter != cProp.getter -> "cProp.getter != cProp.getter" + + cProp.getter == C_prop.getter -> "cProp.getter == C_prop.getter" + C_prop.getter == cProp.getter -> "C_prop.getter == cProp.getter" + cProp.getter == C_propReflect.getter -> "cProp.getter == C_propReflect.getter" + C_propReflect.getter == cProp.getter -> "C_propReflect.getter == cProp.getter" + + // TODO https://youtrack.jetbrains.com/issue/KT-13490 + // cProp.getter != C()::prop.getter -> "cProp.getter != C()::prop.getter" + // cProp.setter != C()::prop.setter -> "cProp.setter != C()::prop.setter" + + else -> "OK" + } \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/equals/receiverInEquals.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/equals/receiverInEquals.kt new file mode 100644 index 00000000000..18bc635d01c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/equals/receiverInEquals.kt @@ -0,0 +1,27 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +package test + +class A { + fun foo() {} + fun bar() {} +} + +val a = A() +val aa = A() + +val aFoo = a::foo +val aBar = a::bar +val aaFoo = aa::foo +val A_foo = A::foo + +fun box(): String = + when { + aFoo != a::foo -> "Bound refs with same receiver SHOULD be equal" + aFoo == aBar -> "Bound refs to different members SHOULD NOT be equal" + aFoo == aaFoo -> "Bound refs with different receiver SHOULD NOT be equal" + aFoo == A_foo -> "Bound ref SHOULD NOT be equal to free ref" + + else -> "OK" + } \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/equals/reflectionReference.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/equals/reflectionReference.kt new file mode 100644 index 00000000000..bd6ca854d2c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/equals/reflectionReference.kt @@ -0,0 +1,35 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* + +class C { + fun foo() {} + val bar = 42 +} + +val C_fooReflect = C::class.functions.find { it.name == "foo" }!! +val C_foo = C::foo +val cFoo = C()::foo + +val C_barReflect = C::class.memberProperties.find { it.name == "bar" }!! +val C_bar = C::bar +val cBar= C()::bar + +val Any.className: String + get() = this::class.qualifiedName!! + +fun box(): String = + when { + C_fooReflect != C_foo -> "C_fooReflect != C_foo, ${C_fooReflect.className}" + C_foo != C_fooReflect -> "C_foo != C_fooReflect, ${C_foo.className}" + C_fooReflect == cFoo -> "C_fooReflect == cFoo, ${C_fooReflect.className}" + cFoo == C_fooReflect -> "cFoo == C_fooReflect, ${cFoo.className}" + C_barReflect != C_bar -> "C_barReflect != C_bar, ${C_barReflect.className}" + C_bar != C_barReflect -> "C_bar != C_barReflect, ${C_bar.className}" + C_barReflect == cBar -> "C_barReflect == cBar, ${C_barReflect.className}" + cBar == C_barReflect -> "cBar == C_barReflect, ${cBar.className}" + else -> "OK" + } \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/inline/simple.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/inline/simple.kt new file mode 100644 index 00000000000..ab672b23ac4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/inline/simple.kt @@ -0,0 +1,5 @@ +inline fun foo(x: () -> String) = x() + +fun String.id() = this + +fun box() = foo("OK"::id) diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/inline/simpleVal.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/inline/simpleVal.kt new file mode 100644 index 00000000000..fea3e21c688 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/inline/simpleVal.kt @@ -0,0 +1,8 @@ +inline fun go(f: () -> String) = f() + +fun String.id(): String = this + +fun box(): String { + val x = "OK" + return go(x::id) +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/kCallableNameIntrinsic.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/kCallableNameIntrinsic.kt new file mode 100644 index 00000000000..a289ba275c4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/kCallableNameIntrinsic.kt @@ -0,0 +1,10 @@ +// Enable when callable references to builtin members is supported +// IGNORE_BACKEND: JS, NATIVE +fun box(): String { + var state = 0 + val name = (state++)::toString.name + if (name != "toString") return "Fail 1: $name" + if (state != 1) return "Fail 2: $state" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/kt12738.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/kt12738.kt new file mode 100644 index 00000000000..fa76e62abbb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/kt12738.kt @@ -0,0 +1,11 @@ +// Enable when callable references to builtin members is supported +// IGNORE_BACKEND: JS, NATIVE +fun get(t: T): () -> String { + return t::toString +} + +fun box(): String { + if (get(null).invoke() != "null") return "Fail null" + + return get("OK").invoke() +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/kt15446.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/kt15446.kt new file mode 100644 index 00000000000..e0c0f55139f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/kt15446.kt @@ -0,0 +1,15 @@ +//WITH_RUNTIME +// IGNORE_BACKEND: JS, NATIVE +fun box(): String { + val a = intArrayOf(1, 2) + val b = arrayOf("OK") + if ((a::component2)() != 2) { + return "fail" + } + + if ((a::get)(1) != 2) { + return "fail" + } + + return (b::get)(0) +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/multiCase.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/multiCase.kt new file mode 100644 index 00000000000..1ffad7fac0e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/multiCase.kt @@ -0,0 +1,51 @@ +class A(var v: Int) { + fun f(x: Int) = x * v +} + +fun A.g(x: Int) = x * f(x); + +var A.w: Int + get() = 1000 * v + set(c: Int) { + v = c + 10 + } + +object F { + var u = 0 +} + +fun box(): String { + val a = A(5) + + val av = a::v + if (av() != 5) return "fail1: ${av()}" + if (av.get() != 5) return "fail2: ${av.get()}" + av.set(7) + if (a.v != 7) return "fail3: ${a.v}" + + val af = a::f + if (af(10) != 70) return "fail4: ${af(10)}" + + val ag = a::g + if (ag(10) != 700) return "fail5: ${ag(10)}" + + val aw = a::w + if (aw() != 7000) return "fail6: ${aw()}" + if (aw.get() != 7000) return "fail7: ${aw.get()}" + aw.set(5) + if (a.v != 15) return "fail8: ${a.v}" + + val fu = F::u + if (fu() != 0) return "fail9: ${fu()}" + if (fu.get() != 0) return "fail10: ${fu.get()}" + fu.set(8) + if (F.u != 8) return "fail11: ${F.u}" + + val x = 100 + + fun A.lf() = v * x; + val alf = a::lf + if (alf() != 1500) return "fail9: ${alf()}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/nullReceiver.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/nullReceiver.kt new file mode 100644 index 00000000000..0111a54d58b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/nullReceiver.kt @@ -0,0 +1,4 @@ +val String?.ok: String + get() = "OK" + +fun box() = (null::ok).get() \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/objectReceiver.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/objectReceiver.kt new file mode 100644 index 00000000000..a03203792d5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/objectReceiver.kt @@ -0,0 +1,5 @@ +object Singleton { + fun ok() = "OK" +} + +fun box() = (Singleton::ok)() \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/primitiveReceiver.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/primitiveReceiver.kt new file mode 100644 index 00000000000..2773e0cdcd1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/primitiveReceiver.kt @@ -0,0 +1,26 @@ +fun Boolean.foo() = 1 +fun Byte.foo() = 2 +fun Short.foo() = 3 +fun Int.foo() = 4 +fun Long.foo() = 5 +fun Char.foo() = 6 +fun Float.foo() = 7 +fun Double.foo() = 8 + +fun testRef(name: String, f: () -> Int, expected: Int) { + val actual = f() + if (actual != expected) throw AssertionError("$name: $actual != $expected") +} + +fun box(): String { + testRef("Boolean", true::foo, 1) + testRef("Byte", 1.toByte()::foo, 2) + testRef("Short", 1.toShort()::foo, 3) + testRef("Int", 1::foo, 4) + testRef("Long", 1L::foo, 5) + testRef("Char", '1'::foo, 6) + testRef("Float", 1.0F::foo, 7) + testRef("Double", 1.0::foo, 8) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/simpleFunction.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/simpleFunction.kt new file mode 100644 index 00000000000..7d19c68d0d1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/simpleFunction.kt @@ -0,0 +1,6 @@ +// Enable when callable references to builtin members is supported +// IGNORE_BACKEND: JS, NATIVE +fun box(): String { + val f = "KOTLIN"::get + return "${f(1)}${f(0)}" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/simpleProperty.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/simpleProperty.kt new file mode 100644 index 00000000000..8da5393394f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/simpleProperty.kt @@ -0,0 +1,8 @@ +// Enable when callable references to builtin members are supported. +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + val f = "kotlin"::length + val result = f.get() + return if (result == 6) "OK" else "Fail: $result" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/bound/syntheticExtensionOnLHS.kt b/backend.native/tests/external/codegen/blackbox/callableReference/bound/syntheticExtensionOnLHS.kt new file mode 100644 index 00000000000..b8be5402715 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/bound/syntheticExtensionOnLHS.kt @@ -0,0 +1,22 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FILE: A.java + +public class A { + private final String field; + + public A(String field) { + this.field = field; + } + + public CharSequence getFoo() { return field; } +} + +// FILE: test.kt + +fun box(): String { + with (A("OK")) { + val k = foo::toString + return k() + } +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/abstractClassMember.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/abstractClassMember.kt new file mode 100644 index 00000000000..515b25914d0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/abstractClassMember.kt @@ -0,0 +1,9 @@ +abstract class A { + abstract fun foo(): String +} + +class B : A() { + override fun foo() = "OK" +} + +fun box(): String = (A::foo)(B()) diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/booleanNotIntrinsic.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/booleanNotIntrinsic.kt new file mode 100644 index 00000000000..09937cd3c5f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/booleanNotIntrinsic.kt @@ -0,0 +1,8 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + if ((Boolean::not)(true) != false) return "Fail 1" + if ((Boolean::not)(false) != true) return "Fail 2" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromClass.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromClass.kt new file mode 100644 index 00000000000..3ed816ee504 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromClass.kt @@ -0,0 +1,11 @@ +class A { + fun foo(k: Int) = k + + fun result() = (A::foo)(this, 111) +} + +fun box(): String { + val result = A().result() + if (result != 111) return "Fail $result" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromExtension.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromExtension.kt new file mode 100644 index 00000000000..9619233c943 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromExtension.kt @@ -0,0 +1,12 @@ +class A { + fun o() = 111 + fun k(k: Int) = k +} + +fun A.foo() = (A::o)(this) + (A::k)(this, 222) + +fun box(): String { + val result = A().foo() + if (result != 333) return "Fail $result" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromTopLevelStringNoArgs.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromTopLevelStringNoArgs.kt new file mode 100644 index 00000000000..4ea10740594 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromTopLevelStringNoArgs.kt @@ -0,0 +1,8 @@ +class A { + fun foo() = "OK" +} + +fun box(): String { + val x = A::foo + return x(A()) +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromTopLevelStringOneStringArg.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromTopLevelStringOneStringArg.kt new file mode 100644 index 00000000000..acdf2f897d5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromTopLevelStringOneStringArg.kt @@ -0,0 +1,8 @@ +class A { + fun foo(result: String) = result +} + +fun box(): String { + val x = A::foo + return x(A(), "OK") +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromTopLevelUnitNoArgs.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromTopLevelUnitNoArgs.kt new file mode 100644 index 00000000000..37ebbdb72eb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromTopLevelUnitNoArgs.kt @@ -0,0 +1,14 @@ +class A { + var result = "Fail" + + fun foo() { + result = "OK" + } +} + +fun box(): String { + val a = A() + val x = A::foo + x(a) + return a.result +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromTopLevelUnitOneStringArg.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromTopLevelUnitOneStringArg.kt new file mode 100644 index 00000000000..3b280c28f34 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/classMemberFromTopLevelUnitOneStringArg.kt @@ -0,0 +1,14 @@ +class A { + var result = "Fail" + + fun foo(newResult: String) { + result = newResult + } +} + +fun box(): String { + val a = A() + val x = A::foo + x(a, "OK") + return a.result +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/constructorFromTopLevelNoArgs.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/constructorFromTopLevelNoArgs.kt new file mode 100644 index 00000000000..db7b7fd01ef --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/constructorFromTopLevelNoArgs.kt @@ -0,0 +1,5 @@ +class A { + var result = "OK" +} + +fun box() = (::A)().result diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/constructorFromTopLevelOneStringArg.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/constructorFromTopLevelOneStringArg.kt new file mode 100644 index 00000000000..63a861dbcf4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/constructorFromTopLevelOneStringArg.kt @@ -0,0 +1,3 @@ +class A(val result: String) + +fun box() = (::A)("OK").result diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/enumValueOfMethod.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/enumValueOfMethod.kt new file mode 100644 index 00000000000..b2f09fae21b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/enumValueOfMethod.kt @@ -0,0 +1,12 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +enum class E { + ENTRY +} + +fun box(): String { + val f = E::valueOf + val result = f("ENTRY") + return if (result == E.ENTRY) "OK" else "Fail $result" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/equalsIntrinsic.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/equalsIntrinsic.kt new file mode 100644 index 00000000000..742fceab72b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/equalsIntrinsic.kt @@ -0,0 +1,6 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class A + +fun box() = if ((A::equals)(A(), A())) "Fail" else "OK" diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromClass.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromClass.kt new file mode 100644 index 00000000000..0248c2f9f2c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromClass.kt @@ -0,0 +1,7 @@ +class A { + fun result() = (A::foo)(this, "OK") +} + +fun A.foo(x: String) = x + +fun box() = A().result() diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromExtension.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromExtension.kt new file mode 100644 index 00000000000..103ceee5cbc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromExtension.kt @@ -0,0 +1,7 @@ +class A + +fun A.foo() = (A::bar)(this, "OK") + +fun A.bar(x: String) = x + +fun box() = A().foo() diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromTopLevelStringNoArgs.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromTopLevelStringNoArgs.kt new file mode 100644 index 00000000000..b5fd42ad9c6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromTopLevelStringNoArgs.kt @@ -0,0 +1,8 @@ +class A + +fun A.foo() = "OK" + +fun box(): String { + val x = A::foo + return x(A()) +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromTopLevelStringOneStringArg.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromTopLevelStringOneStringArg.kt new file mode 100644 index 00000000000..69db0311a69 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromTopLevelStringOneStringArg.kt @@ -0,0 +1,8 @@ +class A + +fun A.foo(result: String) = result + +fun box(): String { + val x = A::foo + return x(A(), "OK") +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromTopLevelUnitNoArgs.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromTopLevelUnitNoArgs.kt new file mode 100644 index 00000000000..b590ad2ec91 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromTopLevelUnitNoArgs.kt @@ -0,0 +1,14 @@ +class A { + var result = "Fail" +} + +fun A.foo() { + result = "OK" +} + +fun box(): String { + val a = A() + val x = A::foo + x(a) + return a.result +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromTopLevelUnitOneStringArg.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromTopLevelUnitOneStringArg.kt new file mode 100644 index 00000000000..aa9d5505bbf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/extensionFromTopLevelUnitOneStringArg.kt @@ -0,0 +1,14 @@ +class A { + var result = "Fail" +} + +fun A.foo(newResult: String) { + result = newResult +} + +fun box(): String { + val a = A() + val x = A::foo + x(a, "OK") + return a.result +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/genericMember.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/genericMember.kt new file mode 100644 index 00000000000..25dabc055f2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/genericMember.kt @@ -0,0 +1,5 @@ +class A(val t: T) { + fun foo(): T = t +} + +fun box() = (A::foo)(A("OK")) diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/getArityViaFunctionImpl.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/getArityViaFunctionImpl.kt new file mode 100644 index 00000000000..eb0d1f31f6f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/getArityViaFunctionImpl.kt @@ -0,0 +1,35 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals +import kotlin.jvm.internal.FunctionImpl + +fun test(f: Function<*>, arity: Int) { + assertEquals(arity, (f as FunctionImpl).getArity()) +} + +fun foo(s: String, i: Int) {} +class A { + fun bar(s: String, i: Int) {} +} +fun Double.baz(s: String, i: Int) {} + +fun box(): String { + test(::foo, 2) + test(A::bar, 3) + test(Double::baz, 3) + + test(::box, 0) + + fun local(x: Int) {} + test(::local, 1) + + test(fun(s: String) = s, 1) + test(fun(){}, 0) + test({}, 0) + test({x: Int -> x}, 1) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/innerConstructorFromClass.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/innerConstructorFromClass.kt new file mode 100644 index 00000000000..31bb102ee62 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/innerConstructorFromClass.kt @@ -0,0 +1,14 @@ +class A { + inner class Inner { + val o = 111 + val k = 222 + } + + fun result() = (A::Inner)(this).o + (A::Inner)(this).k +} + +fun box(): String { + val result = A().result() + if (result != 333) return "Fail $result" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/innerConstructorFromExtension.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/innerConstructorFromExtension.kt new file mode 100644 index 00000000000..bcde4b24cae --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/innerConstructorFromExtension.kt @@ -0,0 +1,14 @@ +class A { + inner class Inner { + val o = 111 + val k = 222 + } +} + +fun A.foo() = (A::Inner)(this).o + (A::Inner)(this).k + +fun box(): String { + val result = A().foo() + if (result != 333) return "Fail $result" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/innerConstructorFromTopLevelNoArgs.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/innerConstructorFromTopLevelNoArgs.kt new file mode 100644 index 00000000000..577eb19e7af --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/innerConstructorFromTopLevelNoArgs.kt @@ -0,0 +1,12 @@ +class A { + inner class Inner { + val o = 111 + val k = 222 + } +} + +fun box(): String { + val result = (A::Inner)((::A)()).o + (A::Inner)(A()).k + if (result != 333) return "Fail $result" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/innerConstructorFromTopLevelOneStringArg.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/innerConstructorFromTopLevelOneStringArg.kt new file mode 100644 index 00000000000..0eb2b831a2b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/innerConstructorFromTopLevelOneStringArg.kt @@ -0,0 +1,9 @@ +class A { + inner class Inner(val result: Int) +} + +fun box(): String { + val result = (A::Inner)((::A)(), 111).result + (A::Inner)(A(), 222).result + if (result != 333) return "Fail $result" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/javaCollectionsStaticMethod.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/javaCollectionsStaticMethod.kt new file mode 100644 index 00000000000..5dc1ab5fe50 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/javaCollectionsStaticMethod.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// KT-5123 + +import java.util.Collections +import java.util.ArrayList + +fun box(): String { + val numbers = ArrayList() + numbers.add(1) + numbers.add(2) + numbers.add(3) + (Collections::rotate)(numbers, 1) + return if ("$numbers" == "[3, 1, 2]") "OK" else "Fail $numbers" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/captureOuter.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/captureOuter.kt new file mode 100644 index 00000000000..e653f8f0574 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/captureOuter.kt @@ -0,0 +1,12 @@ +class Outer { + val result = "OK" + + inner class Inner { + fun foo() = result + } +} + +fun box(): String { + val f = Outer.Inner::foo + return f(Outer().Inner()) +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/classMember.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/classMember.kt new file mode 100644 index 00000000000..72bb8af6e81 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/classMember.kt @@ -0,0 +1,8 @@ +fun box(): String { + class Local { + fun foo() = "OK" + } + + val ref = Local::foo + return ref(Local()) +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/closureWithSideEffect.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/closureWithSideEffect.kt new file mode 100644 index 00000000000..e58484c9479 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/closureWithSideEffect.kt @@ -0,0 +1,9 @@ +fun box(): String { + var result = "Fail" + + fun changeToOK() { result = "OK" } + + val ok = ::changeToOK + ok() + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/constructor.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/constructor.kt new file mode 100644 index 00000000000..291af016082 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/constructor.kt @@ -0,0 +1,7 @@ +fun box(): String { + class A { + val result = "OK" + } + + return (::A)().result +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/constructorWithInitializer.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/constructorWithInitializer.kt new file mode 100644 index 00000000000..0e8c0a25839 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/constructorWithInitializer.kt @@ -0,0 +1,10 @@ +fun box(): String { + class A { + var result: String = "Fail"; + init { + result = "OK" + } + } + + return (::A)().result +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/enumExtendsTrait.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/enumExtendsTrait.kt new file mode 100644 index 00000000000..5ae74283aee --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/enumExtendsTrait.kt @@ -0,0 +1,11 @@ +interface Named { + val name: String +} + +enum class E : Named { + OK +} + +fun box(): String { + return E.OK.name +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/extension.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/extension.kt new file mode 100644 index 00000000000..3919a320e81 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/extension.kt @@ -0,0 +1,6 @@ +class A + +fun box(): String { + fun A.foo() = "OK" + return (A::foo)(A()) +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/extensionToLocalClass.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/extensionToLocalClass.kt new file mode 100644 index 00000000000..43537f177e9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/extensionToLocalClass.kt @@ -0,0 +1,5 @@ +fun box(): String { + class A + fun A.foo() = "OK" + return (A::foo)((::A)()) +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/extensionToPrimitive.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/extensionToPrimitive.kt new file mode 100644 index 00000000000..9cb84f4df07 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/extensionToPrimitive.kt @@ -0,0 +1,4 @@ +fun box(): String { + fun Int.is42With(that: Int) = this + 2 * that == 42 + return if ((Int::is42With)(16, 13)) "OK" else "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/extensionWithClosure.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/extensionWithClosure.kt new file mode 100644 index 00000000000..cbbbcd219b1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/extensionWithClosure.kt @@ -0,0 +1,11 @@ +class A + +fun box(): String { + var result = "Fail" + + fun A.ext() { result = "OK" } + + val f = A::ext + f(A()) + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/genericMember.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/genericMember.kt new file mode 100644 index 00000000000..12e60f50480 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/genericMember.kt @@ -0,0 +1,8 @@ +fun box(): String { + class Id { + fun invoke(t: T) = t + } + + val ref = Id::invoke + return ref(Id(), "OK") +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/localClassMember.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/localClassMember.kt new file mode 100644 index 00000000000..98f62fb5b40 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/localClassMember.kt @@ -0,0 +1,11 @@ +fun box(): String { + val result = "OK" + + class Local { + fun foo() = result + } + + val member = Local::foo + val instance = Local() + return member(instance) +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/localFunctionName.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/localFunctionName.kt new file mode 100644 index 00000000000..8575e9707a9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/localFunctionName.kt @@ -0,0 +1,8 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + fun OK() {} + + return ::OK.name +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/localLocal.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/localLocal.kt new file mode 100644 index 00000000000..a34a24395b6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/localLocal.kt @@ -0,0 +1,10 @@ +fun box(): String { + fun foo(): String { + fun bar() = "OK" + val ref = ::bar + return ref() + } + + val ref = ::foo + return ref() +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/recursiveClosure.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/recursiveClosure.kt new file mode 100644 index 00000000000..75ca4009a47 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/recursiveClosure.kt @@ -0,0 +1,7 @@ +fun foo(until: Int): String { + fun bar(x: Int): String = + if (x == until) "OK" else bar(x + 1) + return (::bar)(0) +} + +fun box() = foo(10) diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/simple.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/simple.kt new file mode 100644 index 00000000000..789703872db --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/simple.kt @@ -0,0 +1,4 @@ +fun box(): String { + fun foo() = "OK" + return (::foo)() +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/simpleClosure.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/simpleClosure.kt new file mode 100644 index 00000000000..5aeb154fbdd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/simpleClosure.kt @@ -0,0 +1,7 @@ +fun box(): String { + val result = "OK" + + fun foo() = result + + return (::foo)() +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/simpleWithArg.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/simpleWithArg.kt new file mode 100644 index 00000000000..e45fce85e2e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/simpleWithArg.kt @@ -0,0 +1,4 @@ +fun box(): String { + fun foo(s: String) = s + return (::foo)("OK") +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/local/unitWithSideEffect.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/unitWithSideEffect.kt new file mode 100644 index 00000000000..5da17e9d5e5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/local/unitWithSideEffect.kt @@ -0,0 +1,15 @@ +var state = 23 + +fun box(): String { + fun incrementState(inc: Int) { + state += inc + } + + val inc = ::incrementState + inc(12) + inc(-5) + inc(27) + inc(-15) + + return if (state == 42) "OK" else "Fail $state" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/nestedConstructorFromClass.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/nestedConstructorFromClass.kt new file mode 100644 index 00000000000..8e0439f4f03 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/nestedConstructorFromClass.kt @@ -0,0 +1,14 @@ +class A { + class Nested { + val o = 111 + val k = 222 + } + + fun result() = (::Nested)().o + (A::Nested)().k +} + +fun box(): String { + val result = A().result() + if (result != 333) return "Fail $result" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/nestedConstructorFromTopLevelNoArgs.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/nestedConstructorFromTopLevelNoArgs.kt new file mode 100644 index 00000000000..f99dd41ae86 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/nestedConstructorFromTopLevelNoArgs.kt @@ -0,0 +1,7 @@ +class A { + class Nested { + val result = "OK" + } +} + +fun box() = (A::Nested)().result diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/nestedConstructorFromTopLevelOneStringArg.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/nestedConstructorFromTopLevelOneStringArg.kt new file mode 100644 index 00000000000..3f0c03c67f3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/nestedConstructorFromTopLevelOneStringArg.kt @@ -0,0 +1,5 @@ +class A { + class Nested(val result: String) +} + +fun box() = (A::Nested)("OK").result diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/newArray.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/newArray.kt new file mode 100644 index 00000000000..f1666e82235 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/newArray.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +private fun upcast(value: T): T = value + +fun box(): String { + upcast<(Int)->ByteArray>(::ByteArray)(10) + upcast<(Int)->IntArray>(::IntArray)(10) + upcast<(Int)->ShortArray>(::ShortArray)(10) + upcast<(Int)->LongArray>(::LongArray)(10) + upcast<(Int)->DoubleArray>(::DoubleArray)(10) + upcast<(Int)->FloatArray>(::FloatArray)(10) + upcast<(Int)->BooleanArray>(::BooleanArray)(10) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/overloadedFun.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/overloadedFun.kt new file mode 100644 index 00000000000..569ef57a1bb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/overloadedFun.kt @@ -0,0 +1,27 @@ +fun foo(): String = "foo1" +fun foo(i: Int): String = "foo2" + +val f1: () -> String = ::foo +val f2: (Int) -> String = ::foo + +fun foo1() {} +fun foo2(i: Int) {} + +fun bar(f: () -> Unit): String = "bar1" +fun bar(f: (Int) -> Unit): String = "bar2" + +fun box(): String { + val x1 = f1() + if (x1 != "foo1") return "Fail 1: $x1" + + val x2 = f2(0) + if (x2 != "foo2") return "Fail 2: $x2" + + val y1 = bar(::foo1) + if (y1 != "bar1") return "Fail 3: $y1" + + val y2 = bar(::foo2) + if (y2 != "bar2") return "Fail 4: $y2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/overloadedFunVsVal.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/overloadedFunVsVal.kt new file mode 100644 index 00000000000..c5a99e074bd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/overloadedFunVsVal.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +import kotlin.reflect.* + +class A { + val x = 1 + fun x(): String = "OK" +} + +val f1: KProperty1 = A::x +val f2: (A) -> String = A::x + +fun box(): String { + val a = A() + + val x1 = f1.get(a) + if (x1 != 1) return "Fail 1: $x1" + + return f2(a) +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/privateClassMember.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/privateClassMember.kt new file mode 100644 index 00000000000..f99ac7e3ad6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/privateClassMember.kt @@ -0,0 +1,7 @@ +class A { + private fun foo() = "OK" + + fun bar() = (A::foo)(this) +} + +fun box() = A().bar() diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/sortListOfStrings.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/sortListOfStrings.kt new file mode 100644 index 00000000000..5672692f9a8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/sortListOfStrings.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME + +fun sort(list: MutableList, comparator: (String, String) -> Int) { + list.sortWith(Comparator(comparator)) +} + +fun compare(s1: String, s2: String) = s1.compareTo(s2) + +fun box(): String { + val l = mutableListOf("d", "b", "c", "e", "a") + sort(l, ::compare) + if (l != listOf("a", "b", "c", "d", "e")) return "Fail: $l" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromClass.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromClass.kt new file mode 100644 index 00000000000..b8ad1d624bb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromClass.kt @@ -0,0 +1,11 @@ +fun foo(o: Int, k: Int) = o + k + +class A { + fun bar() = (::foo)(111, 222) +} + +fun box(): String { + val result = A().bar() + if (result != 333) return "Fail $result" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromExtension.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromExtension.kt new file mode 100644 index 00000000000..f86acf08a0a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromExtension.kt @@ -0,0 +1,11 @@ +fun foo(o: Int, k: Int) = o + k + +class A + +fun A.bar() = (::foo)(111, 222) + +fun box(): String { + val result = A().bar() + if (result != 333) return "Fail $result" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromTopLevelStringNoArgs.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromTopLevelStringNoArgs.kt new file mode 100644 index 00000000000..b7f56d6be82 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromTopLevelStringNoArgs.kt @@ -0,0 +1,6 @@ +fun foo() = "OK" + +fun box(): String { + val x = ::foo + return x() +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromTopLevelStringOneStringArg.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromTopLevelStringOneStringArg.kt new file mode 100644 index 00000000000..78cb93f0873 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromTopLevelStringOneStringArg.kt @@ -0,0 +1,6 @@ +fun foo(x: String) = x + +fun box(): String { + val x = ::foo + return x("OK") +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromTopLevelUnitNoArgs.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromTopLevelUnitNoArgs.kt new file mode 100644 index 00000000000..a388ed73d4e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromTopLevelUnitNoArgs.kt @@ -0,0 +1,11 @@ +var result = "Fail" + +fun foo() { + result = "OK" +} + +fun box(): String { + val x = ::foo + x() + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromTopLevelUnitOneStringArg.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromTopLevelUnitOneStringArg.kt new file mode 100644 index 00000000000..a15697e48b4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/topLevelFromTopLevelUnitOneStringArg.kt @@ -0,0 +1,11 @@ +var result = "Fail" + +fun foo(newResult: String) { + result = newResult +} + +fun box(): String { + val x = ::foo + x("OK") + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/traitImplMethodWithClassReceiver.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/traitImplMethodWithClassReceiver.kt new file mode 100644 index 00000000000..9171f0b094b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/traitImplMethodWithClassReceiver.kt @@ -0,0 +1,11 @@ +interface T { + fun foo() = "OK" +} + +class B : T { + inner class C { + fun bar() = (T::foo)(this@B) + } +} + +fun box() = B().C().bar() diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/function/traitMember.kt b/backend.native/tests/external/codegen/blackbox/callableReference/function/traitMember.kt new file mode 100644 index 00000000000..88cf738eaa7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/function/traitMember.kt @@ -0,0 +1,9 @@ +interface A { + fun foo(): String +} + +class B : A { + override fun foo() = "OK" +} + +fun box() = (A::foo)(B()) diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/accessViaSubclass.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/accessViaSubclass.kt new file mode 100644 index 00000000000..eb2a0728db2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/accessViaSubclass.kt @@ -0,0 +1,9 @@ +abstract class Base { + val result = "OK" +} + +class Derived : Base() + +fun box(): String { + return (Base::result).get(Derived()) +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/delegated.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/delegated.kt new file mode 100644 index 00000000000..00b880be84e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/delegated.kt @@ -0,0 +1,24 @@ +import kotlin.reflect.KProperty + +val four: Int by NumberDecrypter + +class A { + val two: Int by NumberDecrypter +} + +object NumberDecrypter { + operator fun getValue(instance: Any?, data: KProperty<*>) = when (data.name) { + "four" -> 4 + "two" -> 2 + else -> throw AssertionError() + } +} + +fun box(): String { + val x = ::four.get() + if (x != 4) return "Fail x: $x" + val a = A() + val y = A::two.get(a) + if (y != 2) return "Fail y: $y" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/delegatedMutable.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/delegatedMutable.kt new file mode 100644 index 00000000000..3bc30b3c17d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/delegatedMutable.kt @@ -0,0 +1,24 @@ +import kotlin.reflect.KProperty + +var result: String by Delegate + +object Delegate { + var value = "lol" + + operator fun getValue(instance: Any?, data: KProperty<*>): String { + return value + } + + operator fun setValue(instance: Any?, data: KProperty<*>, newValue: String) { + value = newValue + } +} + +fun box(): String { + val f = ::result + if (f.get() != "lol") return "Fail 1: {$f.get()}" + Delegate.value = "rofl" + if (f.get() != "rofl") return "Fail 2: {$f.get()}" + f.set("OK") + return f.get() +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/enumNameOrdinal.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/enumNameOrdinal.kt new file mode 100644 index 00000000000..10ccfbdee1e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/enumNameOrdinal.kt @@ -0,0 +1,11 @@ +enum class E { + I +} + +fun box(): String { + val i = (E::name).get(E.I) + if (i != "I") return "Fail $i" + val n = (E::ordinal).get(E.I) + if (n != 0) return "Fail $n" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/extensionToArray.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/extensionToArray.kt new file mode 100644 index 00000000000..455b69ae0cf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/extensionToArray.kt @@ -0,0 +1,6 @@ +val Array.firstElement: String get() = get(0) + +fun box(): String { + val p = Array::firstElement + return p.get(arrayOf("OK", "Fail")) +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/genericProperty.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/genericProperty.kt new file mode 100644 index 00000000000..a30bcbd89bd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/genericProperty.kt @@ -0,0 +1,21 @@ +//For KT-6020 +import kotlin.reflect.KProperty1 +import kotlin.reflect.KMutableProperty1 +import kotlin.reflect.KProperty + +class Value(var value: T = null as T, var text: String? = null) + +val Value.additionalText by DVal(Value::text) //works + +val Value.additionalValue by DVal(Value::value) //not work + +class DVal>(val kmember: P) { + operator fun getValue(t: T, p: KProperty<*>): R { + return kmember.get(t) + } +} + +fun box(): String { + val p = Value("O", "K") + return p.additionalValue + p.additionalText +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/invokePropertyReference.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/invokePropertyReference.kt new file mode 100644 index 00000000000..617732ae7f0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/invokePropertyReference.kt @@ -0,0 +1,31 @@ +var state = "" + +var topLevel: Int + get() { + state += "1" + return 42 + } + set(value) { + throw AssertionError("Nooo") + } + +class A { + val member: String + get() { + state += "2" + return "42" + } +} + +val A.ext: Any + get() { + state += "3" + return this + } + +fun box(): String { + (::topLevel)() + (A::member)(A()) + (A::ext)(A()) + return if (state == "123") "OK" else "Fail $state" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/javaBeanConvention.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/javaBeanConvention.kt new file mode 100644 index 00000000000..0030d8026c3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/javaBeanConvention.kt @@ -0,0 +1,14 @@ +// Name of the getter should be 'getaBcde' according to JavaBean conventions +var aBcde: Int = 239 + +fun box(): String { + val x = (::aBcde).get() + if (x != 239) return "Fail x: $x" + + (::aBcde).set(42) + + val y = (::aBcde).get() + if (y != 42) return "Fail y: $y" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/kClassInstanceIsInitializedFirst.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/kClassInstanceIsInitializedFirst.kt new file mode 100644 index 00000000000..5ce636926d5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/kClassInstanceIsInitializedFirst.kt @@ -0,0 +1,13 @@ +import kotlin.reflect.KProperty1 + +class A { + companion object { + val ref: KProperty1 = A::foo + } + + val foo: String = "OK" +} + +fun box(): String { + return A.ref.get(A()) +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/kt12044.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/kt12044.kt new file mode 100644 index 00000000000..ea43b14b545 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/kt12044.kt @@ -0,0 +1,12 @@ +// KT-12044 Assertion "Rewrite at slice LEXICAL_SCOPE" for 'if' with property references + +fun box(): String { + data class Pair(val first: F, val second: S) + val (x, y) = + Pair(1, + if (1 == 1) + Pair::first + else + Pair::second) + return y.get(Pair("OK", "Fail")) +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/kt12982_protectedPropertyReference.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/kt12982_protectedPropertyReference.kt new file mode 100644 index 00000000000..7cabd9c6d65 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/kt12982_protectedPropertyReference.kt @@ -0,0 +1,12 @@ +class Foo { + protected var x = 0 + + fun getX() = Foo::x +} + +fun box(): String { + val x = Foo().getX() + val foo = Foo() + x.set(foo, 42) + return if (x.get(foo) == 42) "OK" else "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/kt14330.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/kt14330.kt new file mode 100644 index 00000000000..43969a5fd1a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/kt14330.kt @@ -0,0 +1,8 @@ +data class Foo(var bar: Int?) + +fun box(): String { + val receiver = Foo(1) + Foo::bar.set(receiver, null) + return if (receiver.bar == null) "OK" else "fail ${receiver.bar}" + +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/kt14330_2.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/kt14330_2.kt new file mode 100644 index 00000000000..d0acfccb0bd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/kt14330_2.kt @@ -0,0 +1,14 @@ +var recivier : Any? = "fail" +var value2 : Any? = "fail2" + +var T.bar : T + get() = this + set(value) { recivier = this; value2 = value} + + +fun box(): String { + String?::bar.set(null, null) + if (recivier != null) "fail 1: ${recivier}" + if (value2 != null) "fail 2: ${value2}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/kt15447.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/kt15447.kt new file mode 100644 index 00000000000..d1d9a817df9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/kt15447.kt @@ -0,0 +1,12 @@ +//WITH_RUNTIME + +fun box(): String { + var methodVar = "OK" + + fun localMethod() : String + { + return lazy { methodVar }::value.get() + } + + return localMethod() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/kt6870_privatePropertyReference.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/kt6870_privatePropertyReference.kt new file mode 100644 index 00000000000..4d5560c98af --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/kt6870_privatePropertyReference.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class Test { + private var iv = 1 + + public fun exec() { + val t = object : Thread() { + override fun run() { + Test::iv.get(this@Test) + Test::iv.set(this@Test, 2) + } + } + t.start() + t.join(1000) + } + + fun result() = if (iv == 2) "OK" else "Fail $iv" +} + +fun box(): String { + val t = Test() + t.exec() + return t.result() +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/listOfStringsMapLength.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/listOfStringsMapLength.kt new file mode 100644 index 00000000000..c7c78a24c9e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/listOfStringsMapLength.kt @@ -0,0 +1,7 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String = + if (listOf("abc", "de", "f").map(String::length) == listOf(3, 2, 1)) "OK" else "Fail" diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/localClassVar.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/localClassVar.kt new file mode 100644 index 00000000000..fd45085df67 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/localClassVar.kt @@ -0,0 +1,9 @@ +fun box(): String { + class Local { + var result = "Fail" + } + + val l = Local() + (Local::result).set(l, "OK") + return (Local::result).get(l) +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/overriddenInSubclass.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/overriddenInSubclass.kt new file mode 100644 index 00000000000..d892efcba29 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/overriddenInSubclass.kt @@ -0,0 +1,9 @@ +open class Base { + open val foo = "Base" +} + +class Derived : Base() { + override val foo = "OK" +} + +fun box() = (Base::foo).get(Derived()) diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/privateSetterInsideClass.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/privateSetterInsideClass.kt new file mode 100644 index 00000000000..8674d12a3a8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/privateSetterInsideClass.kt @@ -0,0 +1,18 @@ +import kotlin.reflect.KMutableProperty + +class Bar(name: String) { + var foo: String = name + private set + + fun test() { + val p = Bar::foo + if (p !is KMutableProperty<*>) throw AssertionError("Fail: p is not a KMutableProperty") + p.set(this, "OK") + } +} + +fun box(): String { + val bar = Bar("Fail") + bar.test() + return bar.foo +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/privateSetterOutsideClass.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/privateSetterOutsideClass.kt new file mode 100644 index 00000000000..39ea508e9ba --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/privateSetterOutsideClass.kt @@ -0,0 +1,29 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// See KT-12337 Reference to property with invisible setter should not be a KMutableProperty + +import kotlin.reflect.KProperty1 +import kotlin.reflect.KMutableProperty + +open class Bar(name: String) { + var foo: String = name + private set +} + +class Baz : Bar("") { + fun ref() = Bar::foo +} + +fun box(): String { + val p1: KProperty1 = Bar::foo + if (p1 is KMutableProperty<*>) return "Fail: p1 is a KMutableProperty" + + val p2 = Baz().ref() + if (p2 is KMutableProperty<*>) return "Fail: p2 is a KMutableProperty" + + val p3 = Bar("")::foo + if (p3 is KMutableProperty<*>) return "Fail: p3 is a KMutableProperty" + + return p1.get(Bar("OK")) +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleExtension.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleExtension.kt new file mode 100644 index 00000000000..28d7199fe8d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleExtension.kt @@ -0,0 +1,12 @@ +val String.id: String + get() = this + +fun box(): String { + val pr = String::id + + if (pr.get("123") != "123") return "Fail value: ${pr.get("123")}" + + if (pr.name != "id") return "Fail name: ${pr.name}" + + return pr.get("OK") +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleMember.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleMember.kt new file mode 100644 index 00000000000..39bf36a0707 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleMember.kt @@ -0,0 +1,9 @@ +class A(val x: Int) + +fun box(): String { + val p = A::x + if (p.get(A(42)) != 42) return "Fail 1" + if (p.get(A(-1)) != -1) return "Fail 2" + if (p.name != "x") return "Fail 3" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleMutableExtension.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleMutableExtension.kt new file mode 100644 index 00000000000..e69cbbe72fc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleMutableExtension.kt @@ -0,0 +1,18 @@ +var storage = 0 + +var Int.foo: Int + get() { + return this + storage + } + set(value) { + storage = this + value + } + +fun box(): String { + val pr = Int::foo + if (pr.get(42) != 42) return "Fail 1: ${pr.get(42)}" + pr.set(200, 39) + if (pr.get(-239) != 0) return "Fail 2: ${pr.get(-239)}" + if (storage != 239) return "Fail 3: $storage" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleMutableMember.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleMutableMember.kt new file mode 100644 index 00000000000..f7d815af3fc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleMutableMember.kt @@ -0,0 +1,16 @@ +data class Box(var value: String) + +fun box(): String { + val o = Box("lorem") + val prop = Box::value + + if (prop.get(o) != "lorem") return "Fail 1: ${prop.get(o)}" + prop.set(o, "ipsum") + if (prop.get(o) != "ipsum") return "Fail 2: ${prop.get(o)}" + if (o.value != "ipsum") return "Fail 3: ${o.value}" + o.value = "dolor" + if (prop.get(o) != "dolor") return "Fail 4: ${prop.get(o)}" + if ("$o" != "Box(value=dolor)") return "Fail 5: $o" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleMutableTopLevel.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleMutableTopLevel.kt new file mode 100644 index 00000000000..46abcebe5f9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleMutableTopLevel.kt @@ -0,0 +1,12 @@ +data class Box(val value: String) + +var pr = Box("first") + +fun box(): String { + val property = ::pr + if (property.get() != Box("first")) return "Fail value: ${property.get()}" + if (property.name != "pr") return "Fail name: ${property.name}" + property.set(Box("second")) + if (property.get().value != "second") return "Fail value 2: ${property.get()}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleTopLevel.kt b/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleTopLevel.kt new file mode 100644 index 00000000000..818327da26f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/callableReference/property/simpleTopLevel.kt @@ -0,0 +1,10 @@ +data class Box(val value: String) + +val foo = Box("lol") + +fun box(): String { + val property = ::foo + if (property.get() != Box("lol")) return "Fail value: ${property.get()}" + if (property.name != "foo") return "Fail name: ${property.name}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/as.kt b/backend.native/tests/external/codegen/blackbox/casts/as.kt new file mode 100644 index 00000000000..6b78d69af24 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/as.kt @@ -0,0 +1,11 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun foo(x: Any) = x as Runnable + +fun box(): String { + val r = object : Runnable { + override fun run() {} + } + return if (foo(r) === r) "OK" else "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/asForConstants.kt b/backend.native/tests/external/codegen/blackbox/casts/asForConstants.kt new file mode 100644 index 00000000000..4d0c62414d8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/asForConstants.kt @@ -0,0 +1,41 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + if (check(1, { it as Int }) == "OK") return "fail 1" + if (check(1, { it as Byte }) != "OK") return "fail 2" + if (check(1, { it as Short }) != "OK") return "fail 3" + if (check(1, { it as Long }) != "OK") return "fail 4" + if (check(1, { it as Char }) != "OK") return "fail 5" + if (check(1, { it as Double }) != "OK") return "fail 6" + if (check(1, { it as Float }) != "OK") return "fail 7" + + if (check(1.0, { it as Int }) != "OK") return "fail 11" + if (check(1.0, { it as Byte }) != "OK") return "fail 12" + if (check(1.0, { it as Short }) != "OK") return "fail 13" + if (check(1.0, { it as Long }) != "OK") return "fail 14" + if (check(1.0, { it as Char }) != "OK") return "fail 15" + if (check(1.0, { it as Double }) == "OK") return "fail 16" + if (check(1.0, { it as Float }) != "OK") return "fail 17" + + if (check(1f, { it as Int }) != "OK") return "fail 21" + if (check(1f, { it as Byte }) != "OK") return "fail 22" + if (check(1f, { it as Short }) != "OK") return "fail 23" + if (check(1f, { it as Long }) != "OK") return "fail 24" + if (check(1f, { it as Char }) != "OK") return "fail 25" + if (check(1f, { it as Double }) != "OK") return "fail 26" + if (check(1f, { it as Float }) == "OK") return "fail 27" + + return "OK" +} + +fun check(param: T, f: (T) -> Unit): String { + try { + f(param) + } + catch (e: ClassCastException) { + return "OK" + } + return "fail" +} + diff --git a/backend.native/tests/external/codegen/blackbox/casts/asSafe.kt b/backend.native/tests/external/codegen/blackbox/casts/asSafe.kt new file mode 100644 index 00000000000..3e86a808c45 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/asSafe.kt @@ -0,0 +1,11 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun foo(x: Any) = x as? Runnable + +fun box(): String { + val r = object : Runnable { + override fun run() {} + } + return if (foo(r) === r) "OK" else "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/asSafeFail.kt b/backend.native/tests/external/codegen/blackbox/casts/asSafeFail.kt new file mode 100644 index 00000000000..c3500dd5c1a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/asSafeFail.kt @@ -0,0 +1,16 @@ +class A +class B + +fun box(): String { + val a = A() + a as? B + a as? B ?: "fail" + + if ((A() as? B) != null) return "fail1" + if ((a as? B) != null) return "fail2" + + val v = a as? B ?: "fail" + if (v != "fail") return "fail4" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/asSafeForConstants.kt b/backend.native/tests/external/codegen/blackbox/casts/asSafeForConstants.kt new file mode 100644 index 00000000000..bc7a063340f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/asSafeForConstants.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + if ((1 as? Int) == null) return "fail 1" + if ((1 as? Byte) != null) return "fail 2" + if ((1 as? Short) != null) return "fail 3" + if ((1 as? Long) != null) return "fail 4" + if ((1 as? Char) != null) return "fail 5" + if ((1 as? Double) != null) return "fail 6" + if ((1 as? Float) != null) return "fail 7" + + if ((1.0 as? Int) != null) return "fail 11" + if ((1.0 as? Byte) != null) return "fail 12" + if ((1.0 as? Short) != null) return "fail 13" + if ((1.0 as? Long) != null) return "fail 14" + if ((1.0 as? Char) != null) return "fail 15" + if ((1.0 as? Double) == null) return "fail 16" + if ((1.0 as? Float) != null) return "fail 17" + + if ((1f as? Int) != null) return "fail 21" + if ((1f as? Byte) != null) return "fail 22" + if ((1f as? Short) != null) return "fail 23" + if ((1f as? Long) != null) return "fail 24" + if ((1f as? Char) != null) return "fail 25" + if ((1f as? Double) != null) return "fail 26" + if ((1f as? Float) == null) return "fail 27" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/asUnit.kt b/backend.native/tests/external/codegen/blackbox/casts/asUnit.kt new file mode 100644 index 00000000000..8c11703906c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/asUnit.kt @@ -0,0 +1 @@ +fun box() = if (4 as? Unit != null) "Fail" else "OK" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/asWithGeneric.kt b/backend.native/tests/external/codegen/blackbox/casts/asWithGeneric.kt new file mode 100644 index 00000000000..b8d44d6a517 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/asWithGeneric.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun test1() = null as T +fun test2(): T { + val a : Any? = null + return a as T +} + +fun test3() = null as T + +fun box(): String { + if (test1() != null) return "fail: test1" + if (test2() != null) return "fail: test2" + var result3 = "fail" + try { + test3() + } + catch(e: TypeCastException) { + result3 = "OK" + } + if (result3 != "OK") return "fail: test3" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/castGenericNull.kt b/backend.native/tests/external/codegen/blackbox/casts/castGenericNull.kt new file mode 100644 index 00000000000..42628250375 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/castGenericNull.kt @@ -0,0 +1,13 @@ +fun castToString(t: T) { + t as String +} + + +fun box(): String { + try { + castToString(null) + } catch (e: Exception) { + return "OK" + } + return "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/functions/asFunKBig.kt b/backend.native/tests/external/codegen/blackbox/casts/functions/asFunKBig.kt new file mode 100644 index 00000000000..e6b457326ed --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/functions/asFunKBig.kt @@ -0,0 +1,254 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// This is a big, ugly, semi-auto generated test. +// Use corresponding 'Small' test for debug. + +import kotlin.test.* + +fun fn0() {} +fun fn1(x0: Any) {} +fun fn2(x0: Any, x1: Any) {} +fun fn3(x0: Any, x1: Any, x2: Any) {} +fun fn4(x0: Any, x1: Any, x2: Any, x3: Any) {} +fun fn5(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any) {} +fun fn6(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any) {} +fun fn7(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any) {} +fun fn8(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any) {} +fun fn9(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any) {} +fun fn10(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any) {} +fun fn11(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any) {} +fun fn12(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any) {} +fun fn13(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any) {} +fun fn14(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any) {} +fun fn15(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any) {} +fun fn16(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any) {} +fun fn17(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any) {} +fun fn18(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any) {} +fun fn19(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any) {} +fun fn20(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any) {} +fun fn21(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any) {} +fun fn22(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any, x21: Any) {} + +val fns = arrayOf(::fn0, ::fn1, ::fn2, ::fn3, ::fn4, ::fn5, ::fn6, ::fn7, ::fn8, ::fn9, + ::fn10, ::fn11, ::fn12, ::fn13, ::fn14, ::fn15, ::fn16, ::fn17, ::fn18, ::fn19, + ::fn20, ::fn21, ::fn22) + +inline fun asFailsWithCCE(operation: String, crossinline block: () -> Unit) { + assertFailsWith(ClassCastException::class, "$operation should throw an exception") { + block() + } +} + +inline fun asSucceeds(operation: String, block: () -> Unit) { + block() +} + +interface TestFnBase { + fun testGood(x: Any) + fun testBad(x: Any) +} + +object TestFn0 : TestFnBase { + override fun testGood(x: Any) { x as Function0<*> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function0<*>") { + x as Function0<*> + } +} + +object TestFn1 : TestFnBase { + override fun testGood(x: Any) { x as Function1<*, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function1<*, *>") { + x as Function1<*, *> + } +} + +object TestFn2 : TestFnBase { + override fun testGood(x: Any) { x as Function2<*, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function2<*, *, *>") { + x as Function2<*, *, *> + } +} + +object TestFn3 : TestFnBase { + override fun testGood(x: Any) { x as Function3<*, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function3<*, *, *, *>") { + x as Function3<*, *, *, *> + } +} + +object TestFn4 : TestFnBase { + override fun testGood(x: Any) { x as Function4<*, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function4<*, *, *, *, *>") { + x as Function4<*, *, *, *, *> + } +} + +object TestFn5 : TestFnBase { + override fun testGood(x: Any) { x as Function5<*, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function5<*, *, *, *, *, *>") { + x as Function5<*, *, *, *, *, *> + } +} + +object TestFn6 : TestFnBase { + override fun testGood(x: Any) { x as Function6<*, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function6<*, *, *, *, *, *, *>") { + x as Function6<*, *, *, *, *, *, *> + } +} + +object TestFn7 : TestFnBase { + override fun testGood(x: Any) { x as Function7<*, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function7<*, *, *, *, *, *, *, *>") { + x as Function7<*, *, *, *, *, *, *, *> + } +} + +object TestFn8 : TestFnBase { + override fun testGood(x: Any) { x as Function8<*, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function8<*, *, *, *, *, *, *, *, *>") { + x as Function8<*, *, *, *, *, *, *, *, *> + } +} + +object TestFn9 : TestFnBase { + override fun testGood(x: Any) { x as Function9<*, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function9<*, *, *, *, *, *, *, *, *, *>") { + x as Function9<*, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn10 : TestFnBase { + override fun testGood(x: Any) { x as Function10<*, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function10<*, *, *, *, *, *, *, *, *, *, *>") { + x as Function10<*, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn11 : TestFnBase { + override fun testGood(x: Any) { x as Function11<*, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function11<*, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function11<*, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn12 : TestFnBase { + override fun testGood(x: Any) { x as Function12<*, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function12<*, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn13 : TestFnBase { + override fun testGood(x: Any) { x as Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn14 : TestFnBase { + override fun testGood(x: Any) { x as Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn15 : TestFnBase { + override fun testGood(x: Any) { x as Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn16 : TestFnBase { + override fun testGood(x: Any) { x as Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn17 : TestFnBase { + override fun testGood(x: Any) { x as Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn18 : TestFnBase { + override fun testGood(x: Any) { x as Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn19 : TestFnBase { + override fun testGood(x: Any) { x as Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn20 : TestFnBase { + override fun testGood(x: Any) { x as Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn21 : TestFnBase { + override fun testGood(x: Any) { x as Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn22 : TestFnBase { + override fun testGood(x: Any) { x as Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> } + override fun testBad(x: Any) = + asFailsWithCCE("x as Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +val tests = arrayOf(TestFn0, TestFn1, TestFn2, TestFn3, TestFn4, TestFn5, TestFn6, TestFn7, TestFn8, TestFn9, + TestFn10, TestFn11, TestFn12, TestFn13, TestFn14, TestFn15, TestFn16, TestFn17, TestFn18, TestFn19, + TestFn20, TestFn21, TestFn22) + +fun box(): String { + for (fnI in 0 .. 22) { + for (testI in 0 .. 22) { + if (fnI == testI) { + tests[testI].testGood(fns[fnI]) + } + else { + tests[testI].testBad(fns[fnI]) + } + } + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/functions/asFunKSmall.kt b/backend.native/tests/external/codegen/blackbox/casts/functions/asFunKSmall.kt new file mode 100644 index 00000000000..c4632210b28 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/functions/asFunKSmall.kt @@ -0,0 +1,47 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun fn0() {} +fun fn1(x: Any) {} + +inline fun asFailsWithCCE(operation: String, block: () -> Unit) { + try { + block() + } + catch (e: java.lang.ClassCastException) { + return + } + catch (e: Throwable) { + throw AssertionError("$operation: should throw ClassCastException, got $e") + } + throw AssertionError("$operation: should throw ClassCastException, no exception thrown") +} + +inline fun asSucceeds(operation: String, block: () -> Unit) { + try { + block() + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +class MyFun: Function + +fun box(): String { + val f0 = ::fn0 as Any + val f1 = ::fn1 as Any + + val myFun = MyFun() as Any + + asSucceeds("f0 as Function0<*>") { f0 as Function0<*> } + asFailsWithCCE("f0 as Function1<*, *>") { f0 as Function1<*, *> } + asFailsWithCCE("f1 as Function0<*>") { f1 as Function0<*> } + asSucceeds("f1 as Function1<*, *>") { f1 as Function1<*, *> } + + asFailsWithCCE("myFun as Function0<*>") { myFun as Function0<*> } + asFailsWithCCE("myFun as Function1<*, *>") { myFun as Function1<*, *> } + + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/functions/isFunKBig.kt b/backend.native/tests/external/codegen/blackbox/casts/functions/isFunKBig.kt new file mode 100644 index 00000000000..35d1bfe131e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/functions/isFunKBig.kt @@ -0,0 +1,181 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// This is a big, ugly, semi-auto generated test. +// Use corresponding 'Small' test for debug. + +fun fn0() {} +fun fn1(x0: Any) {} +fun fn2(x0: Any, x1: Any) {} +fun fn3(x0: Any, x1: Any, x2: Any) {} +fun fn4(x0: Any, x1: Any, x2: Any, x3: Any) {} +fun fn5(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any) {} +fun fn6(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any) {} +fun fn7(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any) {} +fun fn8(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any) {} +fun fn9(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any) {} +fun fn10(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any) {} +fun fn11(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any) {} +fun fn12(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any) {} +fun fn13(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any) {} +fun fn14(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any) {} +fun fn15(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any) {} +fun fn16(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any) {} +fun fn17(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any) {} +fun fn18(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any) {} +fun fn19(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any) {} +fun fn20(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any) {} +fun fn21(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any) {} +fun fn22(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any, x21: Any) {} + +val fns = arrayOf(::fn0, ::fn1, ::fn2, ::fn3, ::fn4, ::fn5, ::fn6, ::fn7, ::fn8, ::fn9, + ::fn10, ::fn11, ::fn12, ::fn13, ::fn14, ::fn15, ::fn16, ::fn17, ::fn18, ::fn19, + ::fn20, ::fn21, ::fn22) + +abstract class TestFnBase(val type: String) { + abstract fun testGood(x: Any) + abstract fun testBad(x: Any) + + protected fun assertIs(x: Any, condition: Boolean) { + assert(condition) { "x is $type: failed for $x" } + } + + protected fun assertIsNot(x: Any, condition: Boolean) { + assert(condition) { "x !is $type: failed for $x" } + } +} + +object TestFn0 : TestFnBase("Function0<*>") { + override fun testGood(x: Any) { assertIs(x, x is Function0<*>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function0<*>) } +} + +object TestFn1 : TestFnBase("Function1<*, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function1<*, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function1<*, *>) } +} + +object TestFn2 : TestFnBase("Function2<*, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function2<*, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function2<*, *, *>) } +} + +object TestFn3 : TestFnBase("Function3<*, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function3<*, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function3<*, *, *, *>) } +} + +object TestFn4 : TestFnBase("Function4<*, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function4<*, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function4<*, *, *, *, *>) } +} + +object TestFn5 : TestFnBase("Function5<*, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function5<*, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function5<*, *, *, *, *, *>) } +} + +object TestFn6 : TestFnBase("Function6<*, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function6<*, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function6<*, *, *, *, *, *, *>) } +} + +object TestFn7 : TestFnBase("Function7<*, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function7<*, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function7<*, *, *, *, *, *, *, *>) } +} + +object TestFn8 : TestFnBase("Function8<*, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function8<*, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function8<*, *, *, *, *, *, *, *, *>) } +} + +object TestFn9 : TestFnBase("Function9<*, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function9<*, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function9<*, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn10 : TestFnBase("Function10<*, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function10<*, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function10<*, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn11 : TestFnBase("Function11<*, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function11<*, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function11<*, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn12 : TestFnBase("Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn13 : TestFnBase("Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn14 : TestFnBase("Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn15 : TestFnBase("Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn16 : TestFnBase("Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn17 : TestFnBase("Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn18 : TestFnBase("Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn19 : TestFnBase("Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn20 : TestFnBase("Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn21 : TestFnBase("Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +object TestFn22 : TestFnBase("Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertIs(x, x is Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } + override fun testBad(x: Any) { assertIsNot(x, x !is Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) } +} + +val tests = arrayOf(TestFn0, TestFn1, TestFn2, TestFn3, TestFn4, TestFn5, TestFn6, TestFn7, TestFn8, TestFn9, + TestFn10, TestFn11, TestFn12, TestFn13, TestFn14, TestFn15, TestFn16, TestFn17, TestFn18, TestFn19, + TestFn20, TestFn21, TestFn22) + +fun box(): String { + for (fnI in 0 .. 22) { + for (testI in 0 .. 22) { + if (fnI == testI) { + tests[testI].testGood(fns[fnI]) + } + else { + tests[testI].testBad(fns[fnI]) + } + } + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/functions/isFunKSmall.kt b/backend.native/tests/external/codegen/blackbox/casts/functions/isFunKSmall.kt new file mode 100644 index 00000000000..540798009ff --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/functions/isFunKSmall.kt @@ -0,0 +1,60 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +fun fn0() {} +fun fn1(x: Any) {} + +val lambda0 = {} as () -> Unit +val lambda1 = { x: Any -> } as (Any) -> Unit + +fun Any.extFun() {} + +var Any.extProp: String + get() = "extProp" + set(x: String) {} + +class A { + fun foo() {} +} + +fun box(): String { + val f0 = ::fn0 as Any + val f1 = ::fn1 as Any + + val ef = Any::extFun as Any + val epg = Any::extProp.getter + val eps = Any::extProp.setter + + val afoo = A::foo + + fun local0() {} + fun local1(x: Any) {} + + val localFun0 = ::local0 as Any + val localFun1 = ::local1 as Any + + assert(f0 is Function0<*>) { "Failed: f0 is Function0<*>" } + assert(f1 is Function1<*, *>) { "Failed: f1 is Function1<*, *>" } + assert(f0 !is Function1<*, *>) { "Failed: f0 !is Function1<*, *>" } + assert(f1 !is Function0<*>) { "Failed: f1 !is Function0<*>" } + + assert(lambda0 is Function0<*>) { "Failed: lambda0 is Function0<*>" } + assert(lambda1 is Function1<*, *>) { "Failed: lambda1 is Function1<*, *>" } + assert(lambda0 !is Function1<*, *>) { "Failed: lambda0 !is Function1<*, *>" } + assert(lambda1 !is Function0<*>) { "Failed: lambda1 !is Function0<*>" } + + assert(localFun0 is Function0<*>) { "Failed: localFun0 is Function0<*>" } + assert(localFun1 is Function1<*, *>) { "Failed: localFun1 is Function1<*, *>" } + assert(localFun0 !is Function1<*, *>) { "Failed: localFun0 !is Function1<*, *>" } + assert(localFun1 !is Function0<*>) { "Failed: localFun1 !is Function0<*>" } + + assert(ef is Function1<*, *>) { "Failed: ef is Function1<*, *>" } + assert(epg is Function1<*, *>) { "Failed: epg is Function1<*, *>"} + assert(eps is Function2<*, *, *>) { "Failed: eps is Function2<*, *, *>"} + + assert(afoo is Function1<*, *>) { "afoo is Function1<*, *>" } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/functions/javaTypeIsFunK.kt b/backend.native/tests/external/codegen/blackbox/casts/functions/javaTypeIsFunK.kt new file mode 100644 index 00000000000..ec1c3c21eb6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/functions/javaTypeIsFunK.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: JFun.java + +class JFun implements kotlin.jvm.functions.Function0 { + public String invoke() { + return "OK"; + } +} + +// FILE: test.kt + +fun box(): String { + val jfun = JFun() + val jf = jfun as Any + if (jf is Function0<*>) return jfun() + else return "Failed: jf is Function0<*>" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedAsFunKBig.kt b/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedAsFunKBig.kt new file mode 100644 index 00000000000..af43807ed25 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedAsFunKBig.kt @@ -0,0 +1,277 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// This is a big, ugly, semi-auto generated test. +// Use corresponding 'Small' test for debug. + +import kotlin.test.* + +fun fn0() {} +fun fn1(x0: Any) {} +fun fn2(x0: Any, x1: Any) {} +fun fn3(x0: Any, x1: Any, x2: Any) {} +fun fn4(x0: Any, x1: Any, x2: Any, x3: Any) {} +fun fn5(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any) {} +fun fn6(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any) {} +fun fn7(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any) {} +fun fn8(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any) {} +fun fn9(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any) {} +fun fn10(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any) {} +fun fn11(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any) {} +fun fn12(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any) {} +fun fn13(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any) {} +fun fn14(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any) {} +fun fn15(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any) {} +fun fn16(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any) {} +fun fn17(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any) {} +fun fn18(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any) {} +fun fn19(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any) {} +fun fn20(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any) {} +fun fn21(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any) {} +fun fn22(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any, x21: Any) {} + +val fns = arrayOf(::fn0, ::fn1, ::fn2, ::fn3, ::fn4, ::fn5, ::fn6, ::fn7, ::fn8, ::fn9, + ::fn10, ::fn11, ::fn12, ::fn13, ::fn14, ::fn15, ::fn16, ::fn17, ::fn18, ::fn19, + ::fn20, ::fn21, ::fn22) + +inline fun reifiedAsSucceeds(x: Any, operation: String) { + x as T +} + +inline fun reifiedAsFailsWithCCE(x: Any, operation: String) { + assertFailsWith(ClassCastException::class, "$operation should throw an exception") { + x as T + } +} + +interface TestFnBase { + fun testGood(x: Any) + fun testBad(x: Any) +} + +object TestFn0 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function0<*>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function0<*>") +} + +object TestFn1 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function1<*, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function1<*, *>") +} + +object TestFn2 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function2<*, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function2<*, *, *>") +} + +object TestFn3 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function3<*, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function3<*, *, *, *>") +} + +object TestFn4 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function4<*, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function4<*, *, *, *, *>") +} + +object TestFn5 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function5<*, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function5<*, *, *, *, *, *>") +} + +object TestFn6 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function6<*, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function6<*, *, *, *, *, *, *>") +} + +object TestFn7 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function7<*, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function7<*, *, *, *, *, *, *, *>") +} + +object TestFn8 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function8<*, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function8<*, *, *, *, *, *, *, *, *>") +} + +object TestFn9 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function9<*, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function9<*, *, *, *, *, *, *, *, *, *>") +} + +object TestFn10 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function10<*, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function10<*, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn11 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function11<*, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function11<*, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn12 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn13 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn14 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn15 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn16 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn17 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn18 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn19 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn20 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn21 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn22 : TestFnBase { + override fun testGood(x: Any) = + reifiedAsSucceeds>( + x, "x as Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedAsFailsWithCCE>( + x, "x as Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +val tests = arrayOf(TestFn0, TestFn1, TestFn2, TestFn3, TestFn4, TestFn5, TestFn6, TestFn7, TestFn8, TestFn9, + TestFn10, TestFn11, TestFn12, TestFn13, TestFn14, TestFn15, TestFn16, TestFn17, TestFn18, TestFn19, + TestFn20, TestFn21, TestFn22) + +fun box(): String { + for (fnI in 0 .. 22) { + for (testI in 0 .. 22) { + if (fnI == testI) { + tests[testI].testGood(fns[fnI]) + } + else { + tests[testI].testBad(fns[fnI]) + } + } + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedAsFunKSmall.kt b/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedAsFunKSmall.kt new file mode 100644 index 00000000000..217b36c6597 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedAsFunKSmall.kt @@ -0,0 +1,39 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun fn0() {} +fun fn1(x: Any) {} + +inline fun reifiedAsSucceeds(x: Any, operation: String) { + try { + x as T + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +inline fun reifiedAsFailsWithCCE(x: Any, operation: String) { + try { + x as T + } + catch (e: java.lang.ClassCastException) { + return + } + catch (e: Throwable) { + throw AssertionError("$operation: should throw ClassCastException, got $e") + } + throw AssertionError("$operation: should fail with CCE, no exception thrown") +} + +fun box(): String { + val f0 = ::fn0 as Any + val f1 = ::fn1 as Any + + reifiedAsSucceeds>(f0, "f0 as Function0<*>") + reifiedAsFailsWithCCE>(f0, "f0 as Function1<*, *>") + reifiedAsFailsWithCCE>(f1, "f1 as Function0<*>") + reifiedAsSucceeds>(f1, "f1 as Function1<*, *>") + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedIsFunKBig.kt b/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedIsFunKBig.kt new file mode 100644 index 00000000000..369c215ffa5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedIsFunKBig.kt @@ -0,0 +1,195 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// This is a big, ugly, semi-auto generated test. +// Use corresponding 'Small' test for debug. + +fun fn0() {} +fun fn1(x0: Any) {} +fun fn2(x0: Any, x1: Any) {} +fun fn3(x0: Any, x1: Any, x2: Any) {} +fun fn4(x0: Any, x1: Any, x2: Any, x3: Any) {} +fun fn5(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any) {} +fun fn6(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any) {} +fun fn7(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any) {} +fun fn8(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any) {} +fun fn9(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any) {} +fun fn10(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any) {} +fun fn11(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any) {} +fun fn12(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any) {} +fun fn13(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any) {} +fun fn14(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any) {} +fun fn15(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any) {} +fun fn16(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any) {} +fun fn17(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any) {} +fun fn18(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any) {} +fun fn19(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any) {} +fun fn20(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any) {} +fun fn21(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any) {} +fun fn22(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any, x21: Any) {} + +val fns = arrayOf(::fn0, ::fn1, ::fn2, ::fn3, ::fn4, ::fn5, ::fn6, ::fn7, ::fn8, ::fn9, + ::fn10, ::fn11, ::fn12, ::fn13, ::fn14, ::fn15, ::fn16, ::fn17, ::fn18, ::fn19, + ::fn20, ::fn21, ::fn22) + +inline fun assertReifiedIs(x: Any, type: String) { + val answer: Boolean + try { + answer = x is T + } + catch (e: Throwable) { + throw AssertionError("$x is $type: should not throw exceptions, got $e") + } + assert(answer) { "$x is $type: failed" } +} + +inline fun assertReifiedIsNot(x: Any, type: String) { + val answer: Boolean + try { + answer = x !is T + } + catch (e: Throwable) { + throw AssertionError("$x !is $type: should not throw exceptions, got $e") + } + assert(answer) { "$x !is $type: failed" } +} + +abstract class TestFnBase(val type: String) { + abstract fun testGood(x: Any) + abstract fun testBad(x: Any) +} + +object TestFn0 : TestFnBase("Function0<*>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn1 : TestFnBase("Function1<*, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn2 : TestFnBase("Function2<*, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn3 : TestFnBase("Function3<*, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn4 : TestFnBase("Function4<*, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn5 : TestFnBase("Function5<*, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn6 : TestFnBase("Function6<*, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn7 : TestFnBase("Function7<*, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn8 : TestFnBase("Function8<*, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn9 : TestFnBase("Function9<*, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn10 : TestFnBase("Function10<*, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn11 : TestFnBase("Function11<*, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn12 : TestFnBase("Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn13 : TestFnBase("Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn14 : TestFnBase("Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn15 : TestFnBase("Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn16 : TestFnBase("Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn17 : TestFnBase("Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn18 : TestFnBase("Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn19 : TestFnBase("Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn20 : TestFnBase("Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn21 : TestFnBase("Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +object TestFn22 : TestFnBase("Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + override fun testGood(x: Any) { assertReifiedIs>(x, type) } + override fun testBad(x: Any) { assertReifiedIsNot>(x, type) } +} + +val tests = arrayOf(TestFn0, TestFn1, TestFn2, TestFn3, TestFn4, TestFn5, TestFn6, TestFn7, TestFn8, TestFn9, + TestFn10, TestFn11, TestFn12, TestFn13, TestFn14, TestFn15, TestFn16, TestFn17, TestFn18, TestFn19, + TestFn20, TestFn21, TestFn22) + +fun box(): String { + for (fnI in 0 .. 22) { + for (testI in 0 .. 22) { + if (fnI == testI) { + tests[testI].testGood(fns[fnI]) + } + else { + tests[testI].testBad(fns[fnI]) + } + } + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedIsFunKSmall.kt b/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedIsFunKSmall.kt new file mode 100644 index 00000000000..0850527e1c6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedIsFunKSmall.kt @@ -0,0 +1,41 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun fn0() {} +fun fn1(x: Any) {} + +inline fun assertReifiedIs(x: Any, type: String) { + val answer: Boolean + try { + answer = x is T + } + catch (e: Throwable) { + throw AssertionError("$x is $type: should not throw exceptions, got $e") + } + assert(answer) { "$x is $type: failed" } +} + +inline fun assertReifiedIsNot(x: Any, type: String) { + val answer: Boolean + try { + answer = x !is T + } + catch (e: Throwable) { + throw AssertionError("$x !is $type: should not throw exceptions, got $e") + } + assert(answer) { "$x !is $type: failed" } +} + +fun box(): String { + val f0 = ::fn0 as Any + val f1 = ::fn1 as Any + + assertReifiedIs>(f0, "Function0<*>") + assertReifiedIs>(f1, "Function1<*, *>") + assertReifiedIsNot>(f1, "Function0<*>") + assertReifiedIsNot>(f0, "Function1<*, *>") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedSafeAsFunKBig.kt b/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedSafeAsFunKBig.kt new file mode 100644 index 00000000000..a4664ba6126 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedSafeAsFunKBig.kt @@ -0,0 +1,288 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// This is a big, ugly, semi-auto generated test. +// Use corresponding 'Small' test for debug. + +fun fn0() {} +fun fn1(x0: Any) {} +fun fn2(x0: Any, x1: Any) {} +fun fn3(x0: Any, x1: Any, x2: Any) {} +fun fn4(x0: Any, x1: Any, x2: Any, x3: Any) {} +fun fn5(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any) {} +fun fn6(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any) {} +fun fn7(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any) {} +fun fn8(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any) {} +fun fn9(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any) {} +fun fn10(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any) {} +fun fn11(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any) {} +fun fn12(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any) {} +fun fn13(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any) {} +fun fn14(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any) {} +fun fn15(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any) {} +fun fn16(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any) {} +fun fn17(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any) {} +fun fn18(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any) {} +fun fn19(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any) {} +fun fn20(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any) {} +fun fn21(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any) {} +fun fn22(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any, x21: Any) {} + +val fns = arrayOf(::fn0, ::fn1, ::fn2, ::fn3, ::fn4, ::fn5, ::fn6, ::fn7, ::fn8, ::fn9, + ::fn10, ::fn11, ::fn12, ::fn13, ::fn14, ::fn15, ::fn16, ::fn17, ::fn18, ::fn19, + ::fn20, ::fn21, ::fn22) + +inline fun reifiedSafeAsReturnsNonNull(x: Any?, operation: String) { + val y = try { + x as? T + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } + if (y == null) { + throw AssertionError("$operation: should return non-null, got null") + } +} + +inline fun reifiedSafeAsReturnsNull(x: Any?, operation: String) { + val y = try { + x as? T + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } + if (y != null) { + throw AssertionError("$operation: should return null, got $y") + } +} + +interface TestFnBase { + fun testGood(x: Any) + fun testBad(x: Any) +} + +object TestFn0 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function0<*>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function0<*>") +} + +object TestFn1 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function1<*, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function1<*, *>") +} + +object TestFn2 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function2<*, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function2<*, *, *>") +} + +object TestFn3 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function3<*, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function3<*, *, *, *>") +} + +object TestFn4 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function4<*, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function4<*, *, *, *, *>") +} + +object TestFn5 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function5<*, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function5<*, *, *, *, *, *>") +} + +object TestFn6 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function6<*, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function6<*, *, *, *, *, *, *>") +} + +object TestFn7 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function7<*, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function7<*, *, *, *, *, *, *, *>") +} + +object TestFn8 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function8<*, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function8<*, *, *, *, *, *, *, *, *>") +} + +object TestFn9 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function9<*, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function9<*, *, *, *, *, *, *, *, *, *>") +} + +object TestFn10 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function10<*, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function10<*, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn11 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function11<*, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function11<*, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn12 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn13 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn14 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn15 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn16 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn17 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn18 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn19 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn20 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn21 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +object TestFn22 : TestFnBase { + override fun testGood(x: Any) = + reifiedSafeAsReturnsNonNull>( + x, "x as? Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") + override fun testBad(x: Any) = + reifiedSafeAsReturnsNull>( + x, "x as? Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") +} + +val tests = arrayOf(TestFn0, TestFn1, TestFn2, TestFn3, TestFn4, TestFn5, TestFn6, TestFn7, TestFn8, TestFn9, + TestFn10, TestFn11, TestFn12, TestFn13, TestFn14, TestFn15, TestFn16, TestFn17, TestFn18, TestFn19, + TestFn20, TestFn21, TestFn22) + +fun box(): String { + for (fnI in 0 .. 22) { + for (testI in 0 .. 22) { + if (fnI == testI) { + tests[testI].testGood(fns[fnI]) + } + else { + tests[testI].testBad(fns[fnI]) + } + } + } + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedSafeAsFunKSmall.kt b/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedSafeAsFunKSmall.kt new file mode 100644 index 00000000000..5ba0c0d6b2c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/functions/reifiedSafeAsFunKSmall.kt @@ -0,0 +1,44 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun fn0() {} +fun fn1(x: Any) {} + +inline fun reifiedSafeAsReturnsNonNull(x: Any?, operation: String) { + val y = try { + x as? T + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } + if (y == null) { + throw AssertionError("$operation: should return non-null, got null") + } +} + +inline fun reifiedSafeAsReturnsNull(x: Any?, operation: String) { + val y = try { + x as? T + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } + if (y != null) { + throw AssertionError("$operation: should return null, got $y") + } +} + +fun box(): String { + val f0 = ::fn0 as Any + val f1 = ::fn1 as Any + + reifiedSafeAsReturnsNonNull>(f0, "f0 as Function0<*>") + reifiedSafeAsReturnsNull>(f0, "f0 as Function1<*, *>") + reifiedSafeAsReturnsNull>(f1, "f1 as Function0<*>") + reifiedSafeAsReturnsNonNull>(f1, "f1 as Function1<*, *>") + + reifiedSafeAsReturnsNull>(null, "null as Function0<*>") + reifiedSafeAsReturnsNull>(null, "null as Function1<*, *>") + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/functions/safeAsFunKBig.kt b/backend.native/tests/external/codegen/blackbox/casts/functions/safeAsFunKBig.kt new file mode 100644 index 00000000000..3bcde42c159 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/functions/safeAsFunKBig.kt @@ -0,0 +1,331 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// This is a big, ugly, semi-auto generated test. +// Use corresponding 'Small' test for debug. + +fun fn0() {} +fun fn1(x0: Any) {} +fun fn2(x0: Any, x1: Any) {} +fun fn3(x0: Any, x1: Any, x2: Any) {} +fun fn4(x0: Any, x1: Any, x2: Any, x3: Any) {} +fun fn5(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any) {} +fun fn6(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any) {} +fun fn7(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any) {} +fun fn8(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any) {} +fun fn9(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any) {} +fun fn10(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any) {} +fun fn11(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any) {} +fun fn12(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any) {} +fun fn13(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any) {} +fun fn14(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any) {} +fun fn15(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any) {} +fun fn16(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any) {} +fun fn17(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any) {} +fun fn18(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any) {} +fun fn19(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any) {} +fun fn20(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any) {} +fun fn21(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any) {} +fun fn22(x0: Any, x1: Any, x2: Any, x3: Any, x4: Any, x5: Any, x6: Any, x7: Any, x8: Any, x9: Any, x10: Any, x11: Any, x12: Any, x13: Any, x14: Any, x15: Any, x16: Any, x17: Any, x18: Any, x19: Any, x20: Any, x21: Any) {} + +val fns = arrayOf(::fn0, ::fn1, ::fn2, ::fn3, ::fn4, ::fn5, ::fn6, ::fn7, ::fn8, ::fn9, + ::fn10, ::fn11, ::fn12, ::fn13, ::fn14, ::fn15, ::fn16, ::fn17, ::fn18, ::fn19, + ::fn20, ::fn21, ::fn22) + +inline fun safeAsReturnsNull(operation: String, cast: () -> Any?) { + try { + val x = cast() + assert(x == null) { "$operation: should return null, got $x" } + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +inline fun safeAsReturnsNonNull(operation: String, cast: () -> Any?) { + try { + val x = cast() + assert(x != null) { "$operation: should return non-null" } + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +interface TestFnBase { + abstract fun testGood(x: Any) + abstract fun testBad(x: Any) +} + +object TestFn0 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function0<*>") { + x as? Function0<*> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function0<*>") { + x as? Function0<*> + } +} + +object TestFn1 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function1<*, *>") { + x as? Function1<*, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function1<*, *>") { + x as? Function1<*, *> + } +} + +object TestFn2 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function2<*, *, *>") { + x as? Function2<*, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function2<*, *, *>") { + x as? Function2<*, *, *> + } +} + +object TestFn3 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function3<*, *, *, *>") { + x as? Function3<*, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function3<*, *, *, *>") { + x as? Function3<*, *, *, *> + } +} + +object TestFn4 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function4<*, *, *, *, *>") { + x as? Function4<*, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function4<*, *, *, *, *>") { + x as? Function4<*, *, *, *, *> + } +} + +object TestFn5 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function5<*, *, *, *, *, *>") { + x as? Function5<*, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function5<*, *, *, *, *, *>") { + x as? Function5<*, *, *, *, *, *> + } +} + +object TestFn6 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function6<*, *, *, *, *, *, *>") { + x as? Function6<*, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function6<*, *, *, *, *, *, *>") { + x as? Function6<*, *, *, *, *, *, *> + } +} + +object TestFn7 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function7<*, *, *, *, *, *, *, *>") { + x as? Function7<*, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function7<*, *, *, *, *, *, *, *>") { + x as? Function7<*, *, *, *, *, *, *, *> + } +} + +object TestFn8 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function8<*, *, *, *, *, *, *, *, *>") { + x as? Function8<*, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function8<*, *, *, *, *, *, *, *, *>") { + x as? Function8<*, *, *, *, *, *, *, *, *> + } +} + +object TestFn9 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function9<*, *, *, *, *, *, *, *, *, *>") { + x as? Function9<*, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function9<*, *, *, *, *, *, *, *, *, *>") { + x as? Function9<*, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn10 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function10<*, *, *, *, *, *, *, *, *, *, *>") { + x as? Function10<*, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function10<*, *, *, *, *, *, *, *, *, *, *>") { + x as? Function10<*, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn11 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function11<*, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function11<*, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function11<*, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function11<*, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn12 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function12<*, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function12<*, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function12<*, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn13 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function13<*, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn14 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function14<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn15 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function15<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn16 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function16<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn17 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function17<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn18 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function18<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn19 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function19<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn20 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function20<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn21 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function21<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +object TestFn22 : TestFnBase { + override fun testGood(x: Any) = + safeAsReturnsNonNull("x as? Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } + override fun testBad(x: Any) = + safeAsReturnsNull("x as? Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>") { + x as? Function22<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *> + } +} + +val tests = arrayOf(TestFn0, TestFn1, TestFn2, TestFn3, TestFn4, TestFn5, TestFn6, TestFn7, TestFn8, TestFn9, + TestFn10, TestFn11, TestFn12, TestFn13, TestFn14, TestFn15, TestFn16, TestFn17, TestFn18, TestFn19, + TestFn20, TestFn21, TestFn22) + +fun box(): String { + for (fnI in 0 .. 22) { + for (testI in 0 .. 22) { + if (fnI == testI) { + tests[testI].testGood(fns[fnI]) + } + else { + tests[testI].testBad(fns[fnI]) + } + } + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/functions/safeAsFunKSmall.kt b/backend.native/tests/external/codegen/blackbox/casts/functions/safeAsFunKSmall.kt new file mode 100644 index 00000000000..d413300c13e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/functions/safeAsFunKSmall.kt @@ -0,0 +1,39 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun fn0() {} +fun fn1(x: Any) {} + +inline fun safeAsReturnsNull(operation: String, cast: () -> Any?) { + try { + val x = cast() + assert(x == null) { "$operation: should return null, got $x" } + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +inline fun safeAsReturnsNonNull(operation: String, cast: () -> Any?) { + try { + val x = cast() + assert(x != null) { "$operation: should return non-null" } + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +fun box(): String { + val f0 = ::fn0 as Any + val f1 = ::fn1 as Any + + safeAsReturnsNonNull("f0 as? Function0<*>") { f0 as? Function0<*> } + safeAsReturnsNull("f0 as? Function1<*, *>") { f0 as? Function1<*, *> } + safeAsReturnsNull("f1 as? Function0<*>") { f1 as? Function0<*> } + safeAsReturnsNonNull("f1 as? Function1<*, *>") { f1 as? Function1<*, *> } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/intersectionTypeMultipleBounds.kt b/backend.native/tests/external/codegen/blackbox/casts/intersectionTypeMultipleBounds.kt new file mode 100644 index 00000000000..31183798872 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/intersectionTypeMultipleBounds.kt @@ -0,0 +1,22 @@ +interface A { + fun foo(): Any? + fun bar(): String +} + +interface B { + fun foo(): String +} + +fun bar(x: T): String where T : A, T : B { + if (x.foo().length != 2 || x.foo() != "OK") return "fail 1" + if (x.bar() != "ok") return "fail 2" + + return "OK" +} + +class C : A, B { + override fun foo() = "OK" + override fun bar() = "ok" +} + +fun box(): String = bar(C()) \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/intersectionTypeMultipleBoundsImplicitReceiver.kt b/backend.native/tests/external/codegen/blackbox/casts/intersectionTypeMultipleBoundsImplicitReceiver.kt new file mode 100644 index 00000000000..de3adc56939 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/intersectionTypeMultipleBoundsImplicitReceiver.kt @@ -0,0 +1,16 @@ +interface FirstTrait +interface SecondTrait + +fun T.doSomething(): String where T : FirstTrait, T : SecondTrait { + return "OK" +} + +class Foo : FirstTrait, SecondTrait { + fun bar(): String { + return doSomething() + } +} + +fun box(): String { + return Foo().bar() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/intersectionTypeSmartcast.kt b/backend.native/tests/external/codegen/blackbox/casts/intersectionTypeSmartcast.kt new file mode 100644 index 00000000000..509ef35fabd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/intersectionTypeSmartcast.kt @@ -0,0 +1,27 @@ +interface A { + fun foo(): Any? +} + +interface B { + fun foo(): String +} + +fun bar(x: Any?): String { + if (x is A) { + val k = x.foo() + if (k != "OK") return "fail 1" + } + + if (x is B) { + val k = x.foo() + if (k.length != 2) return "fail 2" + } + + if (x is A && x is B) { + return x.foo() + } + + return "fail 4" +} + +fun box(): String = bar(object : A, B { override fun foo() = "OK" }) \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/intersectionTypeWithMultipleBoundsAsReceiver.kt b/backend.native/tests/external/codegen/blackbox/casts/intersectionTypeWithMultipleBoundsAsReceiver.kt new file mode 100644 index 00000000000..8c58629b05c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/intersectionTypeWithMultipleBoundsAsReceiver.kt @@ -0,0 +1,13 @@ +interface Foo +interface Bar + +class Baz : Foo, Bar + +fun S.bip(): String where S : Foo, S: Bar { + return "OK" +} + +fun box(): String { + val baz = Baz() + return baz.bip() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/intersectionTypeWithoutGenericsAsReceiver.kt b/backend.native/tests/external/codegen/blackbox/casts/intersectionTypeWithoutGenericsAsReceiver.kt new file mode 100644 index 00000000000..52c1ef7e498 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/intersectionTypeWithoutGenericsAsReceiver.kt @@ -0,0 +1,12 @@ +interface A +interface B + +class C : A, B + +fun T.foo(): String where T : A, T : B { + return "OK" +} + +fun box(): String { + return C().foo() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/is.kt b/backend.native/tests/external/codegen/blackbox/casts/is.kt new file mode 100644 index 00000000000..19a3e284e5c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/is.kt @@ -0,0 +1,11 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun foo(x: Any) = x is Runnable + +fun box(): String { + val r = object : Runnable { + override fun run() {} + } + return if (foo(r) && !foo(42)) "OK" else "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/lambdaToUnitCast.kt b/backend.native/tests/external/codegen/blackbox/casts/lambdaToUnitCast.kt new file mode 100644 index 00000000000..29b1ec1cc04 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/lambdaToUnitCast.kt @@ -0,0 +1,9 @@ +// IGNORE_BACKEND: JS, NATIVE +// JS backend does not support Unit well. See KT-13932 + +val foo: () -> Unit = {} + +fun box(): String { + foo() as Unit + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/binaryExpressionCast.kt b/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/binaryExpressionCast.kt new file mode 100644 index 00000000000..8f18303c58c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/binaryExpressionCast.kt @@ -0,0 +1,7 @@ +class Box(val value: T) + +fun box() : String { + val b = Box(2 * 3) + val expected: Long? = 6L + return if (b.value == expected) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/javaBox.kt b/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/javaBox.kt new file mode 100644 index 00000000000..16a7d407e12 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/javaBox.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: Box.java + +public class Box { + private final T value; + + public Box(T value) { + this.value = value; + } + + public static Box create(T defaultValue) { + return new Box(defaultValue); + } + + public T getValue() { + return value; + } +} + +// FILE: test.kt +// See KT-10313: ClassCastException with Generics + +fun box(): String { + val sub = Box(-1) + return if (sub.value == -1L) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/labeledExpressionCast.kt b/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/labeledExpressionCast.kt new file mode 100644 index 00000000000..229afac35f9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/labeledExpressionCast.kt @@ -0,0 +1,7 @@ +class Box(val value: T) + +fun box() : String { + val b = Box(x@ (1 + 2)) + val expected: Long? = 3L + return if (b.value == expected) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/parenthesizedExpressionCast.kt b/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/parenthesizedExpressionCast.kt new file mode 100644 index 00000000000..a70372d5ca4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/parenthesizedExpressionCast.kt @@ -0,0 +1,7 @@ +class Box(val value: T) + +fun box() : String { + val b = Box((-1)) + val expected: Long? = -1L + return if (b.value == expected) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/superConstructor.kt b/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/superConstructor.kt new file mode 100644 index 00000000000..f896fd083f6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/superConstructor.kt @@ -0,0 +1,7 @@ +open class Base(val value: T) +class Box(): Base(-1) + +fun box(): String { + val expected: Long? = -1L + return if (Box().value == expected) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/unaryExpressionCast.kt b/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/unaryExpressionCast.kt new file mode 100644 index 00000000000..6f253b61557 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/unaryExpressionCast.kt @@ -0,0 +1,7 @@ +class Box(val value: T) + +fun box() : String { + val b = Box(-1) + val expected: Long? = -1L + return if (b.value == expected) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/vararg.kt b/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/vararg.kt new file mode 100644 index 00000000000..dab9ff62303 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/literalExpressionAsGenericArgument/vararg.kt @@ -0,0 +1,11 @@ +class Box(val value: T) + +fun run(vararg z: T): Box { + return Box(z[0]) +} + +fun box(): String { + val b = run(-1, -1, -1) + val expected: Long? = -1L + return if (b.value == expected) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/asWithMutable.kt b/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/asWithMutable.kt new file mode 100644 index 00000000000..093fae25b18 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/asWithMutable.kt @@ -0,0 +1,126 @@ +// WITH_RUNTIME + +class Itr : Iterator by ArrayList().iterator() +class MItr : MutableIterator by ArrayList().iterator() +class LItr : ListIterator by ArrayList().listIterator() +class MLItr : MutableListIterator by ArrayList().listIterator() + +class It : Iterable by ArrayList() +class MIt : MutableIterable by ArrayList() +class C : Collection by ArrayList() +class MC : MutableCollection by ArrayList() +class L : List by ArrayList() +class ML : MutableList by ArrayList() +class S : Set by HashSet() +class MS : MutableSet by HashSet() + +class M : Map by HashMap() +class MM : MutableMap by HashMap() + +class ME : Map.Entry { + override val key: String get() = throw UnsupportedOperationException() + override val value: String get() = throw UnsupportedOperationException() +} + +class MME : MutableMap.MutableEntry { + override val key: String get() = throw UnsupportedOperationException() + override val value: String get() = throw UnsupportedOperationException() + override fun setValue(value: String): String = throw UnsupportedOperationException() +} + +inline fun asFailsWithCCE(operation: String, block: () -> Unit) { + try { + block() + } + catch (e: ClassCastException) { + return + } + catch (e: Throwable) { + throw AssertionError("$operation: should throw ClassCastException, got $e") + } + throw AssertionError("$operation: should throw ClassCastException, no exception thrown") +} + +inline fun asSucceeds(operation: String, block: () -> Unit) { + try { + block() + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +fun box(): String { + val itr = Itr() as Any + val mitr = MItr() + + asFailsWithCCE("itr as MutableIterator") { itr as MutableIterator<*> } + asSucceeds("mitr as MutableIterator") { mitr as MutableIterator<*> } + + val litr = LItr() as Any + val mlitr = MLItr() + + asFailsWithCCE("litr as MutableIterator") { litr as MutableIterator<*> } + asFailsWithCCE("litr as MutableListIterator") { litr as MutableListIterator<*> } + asSucceeds("mlitr as MutableIterator") { mlitr as MutableIterator<*> } + asSucceeds("mlitr as MutableListIterator") { mlitr as MutableListIterator<*> } + + val it = It() as Any + val mit = MIt() + val arrayList = ArrayList() + + asFailsWithCCE("it as MutableIterable") { it as MutableIterable<*> } + asSucceeds("mit as MutableIterable") { mit as MutableIterable<*> } + asSucceeds("arrayList as MutableIterable") { arrayList as MutableIterable<*> } + + val coll = C() as Any + val mcoll = MC() + + asFailsWithCCE("coll as MutableIterable") { coll as MutableIterable<*> } + asFailsWithCCE("coll as MutableCollection") { coll as MutableCollection<*> } + asSucceeds("mcoll as MutableIterable") { mcoll as MutableIterable<*> } + asSucceeds("mcoll as MutableCollection") { mcoll as MutableCollection<*> } + asSucceeds("arrayList as MutableCollection") { arrayList as MutableCollection<*> } + + val list = L() as Any + val mlist = ML() + + asFailsWithCCE("list as MutableIterable") { list as MutableIterable<*> } + asFailsWithCCE("list as MutableCollection") { list as MutableCollection<*> } + asFailsWithCCE("list as MutableList") { list as MutableList<*> } + asSucceeds("mlist as MutableIterable") { mlist as MutableIterable<*> } + asSucceeds("mlist as MutableCollection") { mlist as MutableCollection<*> } + asSucceeds("mlist as MutableList") { mlist as MutableList<*> } + + val set = S() as Any + val mset = MS() + val hashSet = HashSet() + + asFailsWithCCE("set as MutableIterable") { set as MutableIterable<*> } + asFailsWithCCE("set as MutableCollection") { set as MutableCollection<*> } + asFailsWithCCE("set as MutableSet") { set as MutableSet<*> } + asSucceeds("mset as MutableIterable") { mset as MutableIterable<*> } + asSucceeds("mset as MutableCollection") { mset as MutableCollection<*> } + asSucceeds("mset as MutableSet") { mset as MutableSet<*> } + asSucceeds("hashSet as MutableSet") { hashSet as MutableSet<*> } + + val map = M() as Any + val mmap = MM() + val hashMap = HashMap() + + asFailsWithCCE("map as MutableMap") { map as MutableMap<*, *> } + asSucceeds("mmap as MutableMap") { mmap as MutableMap<*, *> } + + val entry = ME() as Any + val mentry = MME() + + asFailsWithCCE("entry as MutableMap.MutableEntry") { entry as MutableMap.MutableEntry<*, *> } + asSucceeds("mentry as MutableMap.MutableEntry") { mentry as MutableMap.MutableEntry<*, *> } + + hashMap[""] = "" + val hashMapEntry = hashMap.entries.first() + + asSucceeds("hashMapEntry as MutableMap.MutableEntry") { hashMapEntry as MutableMap.MutableEntry<*, *> } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/isWithMutable.kt b/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/isWithMutable.kt new file mode 100644 index 00000000000..56e8fb846c8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/isWithMutable.kt @@ -0,0 +1,111 @@ +// WITH_RUNTIME + +class Itr : Iterator by ArrayList().iterator() +class MItr : MutableIterator by ArrayList().iterator() +class LItr : ListIterator by ArrayList().listIterator() +class MLItr : MutableListIterator by ArrayList().listIterator() + +class It : Iterable by ArrayList() +class MIt : MutableIterable by ArrayList() +class C : Collection by ArrayList() +class MC : MutableCollection by ArrayList() +class L : List by ArrayList() +class ML : MutableList by ArrayList() +class S : Set by HashSet() +class MS : MutableSet by HashSet() + +class M : Map by HashMap() +class MM : MutableMap by HashMap() + +class ME : Map.Entry { + override val key: String get() = throw UnsupportedOperationException() + override val value: String get() = throw UnsupportedOperationException() +} + +class MME : MutableMap.MutableEntry { + override val key: String get() = throw UnsupportedOperationException() + override val value: String get() = throw UnsupportedOperationException() + override fun setValue(value: String): String = throw UnsupportedOperationException() +} + +fun assert(condition: Boolean, message: () -> String) { if (!condition) throw AssertionError(message())} + +fun box(): String { + val itr = Itr() as Any + val mitr = MItr() + + assert(itr !is MutableIterator<*>) { "Itr should satisfy '!is MutableIterator'" } + assert(mitr is MutableIterator<*>) { "MItr should satisfy 'is MutableIterator'" } + + val litr = LItr() as Any + val mlitr = MLItr() + + assert(litr !is MutableIterator<*>) { "LItr should satisfy '!is MutableIterator'" } + assert(litr !is MutableListIterator<*>) { "LItr should satisfy '!is MutableListIterator'" } + assert(mlitr is MutableListIterator<*>) { "MLItr should satisfy 'is MutableListIterator'" } + + val it = It() as Any + val mit = MIt() + val arrayList = ArrayList() + + assert(it !is MutableIterable<*>) { "It should satisfy '!is MutableIterable'" } + assert(mit is MutableIterable<*>) { "MIt should satisfy 'is MutableIterable'" } + assert(arrayList is MutableIterable<*>) { "ArrayList should satisfy 'is MutableIterable'" } + + val coll = C() as Any + val mcoll = MC() + + assert(coll !is MutableCollection<*>) { "C should satisfy '!is MutableCollection'" } + assert(coll !is MutableIterable<*>) { "C should satisfy '!is MutableIterable'" } + assert(mcoll is MutableCollection<*>) { "MC should satisfy 'is MutableCollection'" } + assert(mcoll is MutableIterable<*>) { "MC should satisfy 'is MutableIterable'" } + assert(arrayList is MutableCollection<*>) { "ArrayList should satisfy 'is MutableCollection'" } + + val list = L() as Any + val mlist = ML() + + assert(list !is MutableList<*>) { "L should satisfy '!is MutableList'" } + assert(list !is MutableCollection<*>) { "L should satisfy '!is MutableCollection'" } + assert(list !is MutableIterable<*>) { "L should satisfy '!is MutableIterable'" } + assert(mlist is MutableList<*>) { "ML should satisfy 'is MutableList'" } + assert(mlist is MutableCollection<*>) { "ML should satisfy 'is MutableCollection'" } + assert(mlist is MutableIterable<*>) { "ML should satisfy 'is MutableIterable'" } + assert(arrayList is MutableList<*>) { "ArrayList should satisfy 'is MutableList'" } + + val set = S() as Any + val mset = MS() + val hashSet = HashSet() + + assert(set !is MutableSet<*>) { "S should satisfy '!is MutableSet'" } + assert(set !is MutableCollection<*>) { "S should satisfy '!is MutableCollection'" } + assert(set !is MutableIterable<*>) { "S should satisfy '!is MutableIterable'" } + assert(mset is MutableSet<*>) { "MS should satisfy 'is MutableSet'" } + assert(mset is MutableCollection<*>) { "MS should satisfy 'is MutableCollection'" } + assert(mset is MutableIterable<*>) { "MS should satisfy 'is MutableIterable'" } + assert(hashSet is MutableSet<*>) { "HashSet should satisfy 'is MutableSet'" } + assert(hashSet is MutableCollection<*>) { "HashSet should satisfy 'is MutableCollection'" } + assert(hashSet is MutableIterable<*>) { "HashSet should satisfy 'is MutableIterable'" } + + val map = M() as Any + val mmap = MM() + val hashMap = HashMap() + + assert(map !is MutableMap<*, *>) { "M should satisfy '!is MutableMap'" } + assert(mmap is MutableMap<*, *>) { "MM should satisfy 'is MutableMap'"} + assert(hashMap is MutableMap<*, *>) { "HashMap should satisfy 'is MutableMap'" } + + val entry = ME() as Any + val mentry = MME() + + hashMap[""] = "" + val hashMapEntry = hashMap.entries.first() + + assert(entry !is MutableMap.MutableEntry<*, *>) { "ME should satisfy '!is MutableMap.MutableEntry'"} + assert(mentry is MutableMap.MutableEntry<*, *>) { "MME should satisfy 'is MutableMap.MutableEntry'"} + assert(hashMapEntry is MutableMap.MutableEntry<*, *>) { "HashMap.Entry should satisfy 'is MutableMap.MutableEntry'"} + + assert((mlist as Any) !is MutableSet<*>) { "ML !is MutableSet" } + assert((mlist as Any) !is MutableIterator<*>) { "ML !is MutableIterator" } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/mutabilityMarkerInterfaces.kt b/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/mutabilityMarkerInterfaces.kt new file mode 100644 index 00000000000..5aa856a189a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/mutabilityMarkerInterfaces.kt @@ -0,0 +1,60 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +abstract class Itr : Iterator +abstract class MItr : MutableIterator +abstract class LItr : ListIterator +abstract class MLItr : MutableListIterator +abstract class It : Iterable +abstract class MIt : MutableIterable +abstract class C : Collection +abstract class MC : MutableCollection +abstract class L : List +abstract class ML : MutableList +abstract class S : Set +abstract class MS : MutableSet +abstract class M : Map +abstract class MM : MutableMap +abstract class ME : Map.Entry +abstract class MME : MutableMap.MutableEntry + +abstract class L2 : L() +abstract class ML2 : ML() + +abstract class Weird : Iterator, MutableList + +fun expectInterfaces(jClass: Class<*>, expectedInterfaceNames: Set) { + val actualInterfaceNames = jClass.getInterfaces().mapTo(linkedSetOf()) { it.name } + + assert(actualInterfaceNames == expectedInterfaceNames) { + "${jClass.name}: interfaces: expected: $expectedInterfaceNames; actual: $actualInterfaceNames" + } +} + +fun box(): String { + expectInterfaces(Itr::class.java, setOf("java.util.Iterator", "kotlin.jvm.internal.markers.KMappedMarker")) + expectInterfaces(MItr::class.java, setOf("java.util.Iterator", "kotlin.jvm.internal.markers.KMutableIterator")) + expectInterfaces(LItr::class.java, setOf("java.util.ListIterator", "kotlin.jvm.internal.markers.KMappedMarker")) + expectInterfaces(MLItr::class.java, setOf("java.util.ListIterator", "kotlin.jvm.internal.markers.KMutableListIterator")) + expectInterfaces(It::class.java, setOf("java.lang.Iterable", "kotlin.jvm.internal.markers.KMappedMarker")) + expectInterfaces(MIt::class.java, setOf("java.lang.Iterable", "kotlin.jvm.internal.markers.KMutableIterable")) + expectInterfaces(C::class.java, setOf("java.util.Collection", "kotlin.jvm.internal.markers.KMappedMarker")) + expectInterfaces(MC::class.java, setOf("java.util.Collection", "kotlin.jvm.internal.markers.KMutableCollection")) + expectInterfaces(L::class.java, setOf("java.util.List", "kotlin.jvm.internal.markers.KMappedMarker")) + expectInterfaces(ML::class.java, setOf("java.util.List", "kotlin.jvm.internal.markers.KMutableList")) + expectInterfaces(S::class.java, setOf("java.util.Set", "kotlin.jvm.internal.markers.KMappedMarker")) + expectInterfaces(MS::class.java, setOf("java.util.Set", "kotlin.jvm.internal.markers.KMutableSet")) + expectInterfaces(M::class.java, setOf("java.util.Map", "kotlin.jvm.internal.markers.KMappedMarker")) + expectInterfaces(MM::class.java, setOf("java.util.Map", "kotlin.jvm.internal.markers.KMutableMap")) + expectInterfaces(ME::class.java, setOf("java.util.Map\$Entry", "kotlin.jvm.internal.markers.KMappedMarker")) + expectInterfaces(MME::class.java, setOf("java.util.Map\$Entry", "kotlin.jvm.internal.markers.KMutableMap\$Entry")) + expectInterfaces(L2::class.java, setOf()) + expectInterfaces(ML2::class.java, setOf()) + expectInterfaces(Weird::class.java, + setOf("java.util.Iterator", "kotlin.jvm.internal.markers.KMappedMarker", + "java.util.List", "kotlin.jvm.internal.markers.KMutableList")) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/reifiedAsWithMutable.kt b/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/reifiedAsWithMutable.kt new file mode 100644 index 00000000000..77d2d3b8683 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/reifiedAsWithMutable.kt @@ -0,0 +1,128 @@ +// WITH_RUNTIME + +class Itr : Iterator by ArrayList().iterator() +class MItr : MutableIterator by ArrayList().iterator() +class LItr : ListIterator by ArrayList().listIterator() +class MLItr : MutableListIterator by ArrayList().listIterator() + +class It : Iterable by ArrayList() +class MIt : MutableIterable by ArrayList() +class C : Collection by ArrayList() +class MC : MutableCollection by ArrayList() +class L : List by ArrayList() +class ML : MutableList by ArrayList() +class S : Set by HashSet() +class MS : MutableSet by HashSet() + +class M : Map by HashMap() +class MM : MutableMap by HashMap() + +class ME : Map.Entry { + override val key: String get() = throw UnsupportedOperationException() + override val value: String get() = throw UnsupportedOperationException() +} + +class MME : MutableMap.MutableEntry { + override val key: String get() = throw UnsupportedOperationException() + override val value: String get() = throw UnsupportedOperationException() + override fun setValue(value: String): String = throw UnsupportedOperationException() +} + +inline fun reifiedAsSucceeds(x: Any, operation: String) { + try { + x as T + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +inline fun reifiedAsFailsWithCCE(x: Any, operation: String) { + try { + x as T + } + catch (e: ClassCastException) { + return + } + catch (e: Throwable) { + throw AssertionError("$operation: should throw ClassCastException, got $e") + } + throw AssertionError("$operation: should fail with CCE, no exception thrown") +} + +fun box(): String { + val itr = Itr() as Any + val mitr = MItr() + + reifiedAsFailsWithCCE>(itr, "reifiedAs>(itr)") + reifiedAsSucceeds>(mitr, "reifiedAs>(mitr)") + + val litr = LItr() as Any + val mlitr = MLItr() + + reifiedAsFailsWithCCE>(litr, "reifiedAs>(litr)") + reifiedAsFailsWithCCE>(litr, "reifiedAs>(litr)") + reifiedAsSucceeds>(mlitr, "reifiedAs>(mlitr)") + + val it = It() as Any + val mit = MIt() + val arrayList = ArrayList() + + reifiedAsFailsWithCCE>(it, "reifiedAs>(it)") + reifiedAsSucceeds>(mit, "reifiedAs>(mit)") + reifiedAsSucceeds>(arrayList, "reifiedAs>(arrayList)") + + val coll = C() as Any + val mcoll = MC() + + reifiedAsFailsWithCCE>(coll, "reifiedAs>(coll)") + reifiedAsFailsWithCCE>(coll, "reifiedAs>(coll)") + reifiedAsSucceeds>(mcoll, "reifiedAs>(mcoll)") + reifiedAsSucceeds>(mcoll, "reifiedAs>(mcoll)") + reifiedAsSucceeds>(arrayList, "reifiedAs>(arrayList)") + + val list = L() as Any + val mlist = ML() + + reifiedAsFailsWithCCE>(list, "reifiedAs>(list)") + reifiedAsFailsWithCCE>(list, "reifiedAs>(list)") + reifiedAsFailsWithCCE>(list, "reifiedAs>(list)") + reifiedAsSucceeds>(mlist, "reifiedAs>(mlist)") + reifiedAsSucceeds>(mlist, "reifiedAs>(mlist)") + reifiedAsSucceeds>(mlist, "reifiedAs>(mlist)") + reifiedAsSucceeds>(arrayList, "reifiedAs>(arrayList)") + + val set = S() as Any + val mset = MS() + val hashSet = HashSet() + + reifiedAsFailsWithCCE>(set, "reifiedAs>(set)") + reifiedAsFailsWithCCE>(set, "reifiedAs>(set)") + reifiedAsFailsWithCCE>(set, "reifiedAs>(set)") + reifiedAsSucceeds>(mset, "reifiedAs>(mset)") + reifiedAsSucceeds>(mset, "reifiedAs>(mset)") + reifiedAsSucceeds>(mset, "reifiedAs>(mset)") + reifiedAsSucceeds>(hashSet, "reifiedAs>(hashSet)") + reifiedAsSucceeds>(hashSet, "reifiedAs>(hashSet)") + reifiedAsSucceeds>(hashSet, "reifiedAs>(hashSet)") + + val map = M() as Any + val mmap = MM() + val hashMap = HashMap() + + reifiedAsFailsWithCCE>(map, "reifiedAs>(map)") + reifiedAsSucceeds>(mmap, "reifiedAs>(mmap)") + reifiedAsSucceeds>(hashMap, "reifiedAs>(hashMap)") + + val entry = ME() as Any + val mentry = MME() + + hashMap[""] = "" + val hashMapEntry = hashMap.entries.first() + + reifiedAsFailsWithCCE>(entry, "reifiedAs>(entry)") + reifiedAsSucceeds>(mentry, "reifiedAs>(mentry)") + reifiedAsSucceeds>(hashMapEntry, "reifiedAs>(hashMapEntry)") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/reifiedIsWithMutable.kt b/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/reifiedIsWithMutable.kt new file mode 100644 index 00000000000..df6e233f20a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/reifiedIsWithMutable.kt @@ -0,0 +1,111 @@ +// WITH_RUNTIME + +class Itr : Iterator by ArrayList().iterator() +class MItr : MutableIterator by ArrayList().iterator() +class LItr : ListIterator by ArrayList().listIterator() +class MLItr : MutableListIterator by ArrayList().listIterator() + +class It : Iterable by ArrayList() +class MIt : MutableIterable by ArrayList() +class C : Collection by ArrayList() +class MC : MutableCollection by ArrayList() +class L : List by ArrayList() +class ML : MutableList by ArrayList() +class S : Set by HashSet() +class MS : MutableSet by HashSet() + +class M : Map by HashMap() +class MM : MutableMap by HashMap() + +class ME : Map.Entry { + override val key: String get() = throw UnsupportedOperationException() + override val value: String get() = throw UnsupportedOperationException() +} + +class MME : MutableMap.MutableEntry { + override val key: String get() = throw UnsupportedOperationException() + override val value: String get() = throw UnsupportedOperationException() + override fun setValue(value: String): String = throw UnsupportedOperationException() +} + +inline fun reifiedIs(x: Any): Boolean = x is T +inline fun reifiedIsNot(x: Any): Boolean = x !is T + +fun assert(condition: Boolean, message: () -> String) { if (!condition) throw AssertionError(message())} + +fun box(): String { + val itr = Itr() as Any + val mitr = MItr() + + assert(reifiedIsNot>(itr)) { "reifiedIsNot>(itr)" } + assert(reifiedIs>(mitr)) { "reifiedIs>(mitr)" } + + val litr = LItr() as Any + val mlitr = MLItr() + + assert(reifiedIsNot>(litr)) { "reifiedIsNot>(litr)" } + assert(reifiedIsNot>(litr)) { "reifiedIsNot>(litr)" } + assert(reifiedIs>(mlitr)) { "reifiedIs>(mlitr)" } + + val it = It() as Any + val mit = MIt() + val arrayList = ArrayList() + + assert(reifiedIsNot>(it)) { "reifiedIsNot>(it)" } + assert(reifiedIs>(mit)) { "reifiedIs>(mit)" } + assert(reifiedIs>(arrayList)) { "reifiedIs>(arrayList)" } + + val coll = C() as Any + val mcoll = MC() + + assert(reifiedIsNot>(coll)) { "reifiedIsNot>(coll)" } + assert(reifiedIsNot>(coll)) { "reifiedIsNot>(coll)" } + assert(reifiedIs>(mcoll)) { "reifiedIs>(mcoll)" } + assert(reifiedIs>(mcoll)) { "reifiedIs>(mcoll)" } + assert(reifiedIs>(arrayList)) { "reifiedIs>(arrayList)" } + + val list = L() as Any + val mlist = ML() + + assert(reifiedIsNot>(list)) { "reifiedIsNot>(list)" } + assert(reifiedIsNot>(list)) { "reifiedIsNot>(list)" } + assert(reifiedIsNot>(list)) { "reifiedIsNot>(list)" } + assert(reifiedIs>(mlist)) { "reifiedIs>(mlist)" } + assert(reifiedIs>(mlist)) { "reifiedIs>(mlist)" } + assert(reifiedIs>(mlist)) { "reifiedIs>(mlist)" } + assert(reifiedIs>(arrayList)) { "reifiedIs>(arrayList)" } + + val set = S() as Any + val mset = MS() + val hashSet = HashSet() + + assert(reifiedIsNot>(set)) { "reifiedIsNot>(set)" } + assert(reifiedIsNot>(set)) { "reifiedIsNot>(set)" } + assert(reifiedIsNot>(set)) { "reifiedIsNot>(set)" } + assert(reifiedIs>(mset)) { "reifiedIs>(mset)" } + assert(reifiedIs>(mset)) { "reifiedIs>(mset)" } + assert(reifiedIs>(mset)) { "reifiedIs>(mset)" } + assert(reifiedIs>(hashSet)) { "reifiedIs>(hashSet)" } + assert(reifiedIs>(hashSet)) { "reifiedIs>(hashSet)" } + assert(reifiedIs>(hashSet)) { "reifiedIs>(hashSet)" } + + val map = M() as Any + val mmap = MM() + val hashMap = HashMap() + + assert(reifiedIsNot>(map)) { "reifiedIsNot>(map)" } + assert(reifiedIs>(mmap)) { "reifiedIs>(mmap)"} + assert(reifiedIs>(hashMap)) { "reifiedIs>(hashMap)" } + + val entry = ME() as Any + val mentry = MME() + + hashMap[""] = "" + val hashMapEntry = hashMap.entries.first() + + assert(reifiedIsNot>(entry)) { "reifiedIsNot>(entry)"} + assert(reifiedIs>(mentry)) { "reifiedIs>(mentry)"} + assert(reifiedIs>(hashMapEntry)) { "reifiedIs>(hashMapEntry)"} + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/reifiedSafeAsWithMutable.kt b/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/reifiedSafeAsWithMutable.kt new file mode 100644 index 00000000000..a54ad8b239f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/reifiedSafeAsWithMutable.kt @@ -0,0 +1,139 @@ +// WITH_RUNTIME + +class Itr : Iterator by ArrayList().iterator() +class MItr : MutableIterator by ArrayList().iterator() +class LItr : ListIterator by ArrayList().listIterator() +class MLItr : MutableListIterator by ArrayList().listIterator() + +class It : Iterable by ArrayList() +class MIt : MutableIterable by ArrayList() +class C : Collection by ArrayList() +class MC : MutableCollection by ArrayList() +class L : List by ArrayList() +class ML : MutableList by ArrayList() +class S : Set by HashSet() +class MS : MutableSet by HashSet() + +class M : Map by HashMap() +class MM : MutableMap by HashMap() + +class ME : Map.Entry { + override val key: String get() = throw UnsupportedOperationException() + override val value: String get() = throw UnsupportedOperationException() +} + +class MME : MutableMap.MutableEntry { + override val key: String get() = throw UnsupportedOperationException() + override val value: String get() = throw UnsupportedOperationException() + override fun setValue(value: String): String = throw UnsupportedOperationException() +} + +inline fun reifiedSafeAsReturnsNonNull(x: Any?, operation: String) { + val y = try { + x as? T + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } + if (y == null) { + throw AssertionError("$operation: should return non-null, got null") + } +} + +inline fun reifiedSafeAsReturnsNull(x: Any?, operation: String) { + val y = try { + x as? T + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } + if (y != null) { + throw AssertionError("$operation: should return null, got $y") + } +} + +fun box(): String { + val itr = Itr() as Any + val mitr = MItr() + + reifiedSafeAsReturnsNull>(itr, "reifiedSafeAs>(itr)") + reifiedSafeAsReturnsNonNull>(mitr, "reifiedSafeAs>(mitr)") + + val litr = LItr() as Any + val mlitr = MLItr() + + reifiedSafeAsReturnsNull>(litr, "reifiedSafeAs>(litr)") + reifiedSafeAsReturnsNull>(litr, "reifiedSafeAs>(litr)") + reifiedSafeAsReturnsNonNull>(mlitr, "reifiedSafeAs>(mlitr)") + + val it = It() as Any + val mit = MIt() + val arrayList = ArrayList() + + reifiedSafeAsReturnsNull>(it, "reifiedSafeAs>(it)") + reifiedSafeAsReturnsNonNull>(mit, "reifiedSafeAs>(mit)") + reifiedSafeAsReturnsNonNull>(arrayList, "reifiedSafeAs>(arrayList)") + + val coll = C() as Any + val mcoll = MC() + + reifiedSafeAsReturnsNull>(coll, "reifiedSafeAs>(coll)") + reifiedSafeAsReturnsNull>(coll, "reifiedSafeAs>(coll)") + reifiedSafeAsReturnsNonNull>(mcoll, "reifiedSafeAs>(mcoll)") + reifiedSafeAsReturnsNonNull>(mcoll, "reifiedSafeAs>(mcoll)") + reifiedSafeAsReturnsNonNull>(arrayList, "reifiedSafeAs>(arrayList)") + + val list = L() as Any + val mlist = ML() + + reifiedSafeAsReturnsNull>(list, "reifiedSafeAs>(list)") + reifiedSafeAsReturnsNull>(list, "reifiedSafeAs>(list)") + reifiedSafeAsReturnsNull>(list, "reifiedSafeAs>(list)") + reifiedSafeAsReturnsNonNull>(mlist, "reifiedSafeAs>(mlist)") + reifiedSafeAsReturnsNonNull>(mlist, "reifiedSafeAs>(mlist)") + reifiedSafeAsReturnsNonNull>(mlist, "reifiedSafeAs>(mlist)") + reifiedSafeAsReturnsNonNull>(arrayList, "reifiedSafeAs>(arrayList)") + + val set = S() as Any + val mset = MS() + val hashSet = HashSet() + + reifiedSafeAsReturnsNull>(set, "reifiedSafeAs>(set)") + reifiedSafeAsReturnsNull>(set, "reifiedSafeAs>(set)") + reifiedSafeAsReturnsNull>(set, "reifiedSafeAs>(set)") + reifiedSafeAsReturnsNonNull>(mset, "reifiedSafeAs>(mset)") + reifiedSafeAsReturnsNonNull>(mset, "reifiedSafeAs>(mset)") + reifiedSafeAsReturnsNonNull>(mset, "reifiedSafeAs>(mset)") + reifiedSafeAsReturnsNonNull>(hashSet, "reifiedSafeAs>(hashSet)") + reifiedSafeAsReturnsNonNull>(hashSet, "reifiedSafeAs>(hashSet)") + reifiedSafeAsReturnsNonNull>(hashSet, "reifiedSafeAs>(hashSet)") + + val map = M() as Any + val mmap = MM() + val hashMap = HashMap() + + reifiedSafeAsReturnsNull>(map, "reifiedSafeAs>(map)") + reifiedSafeAsReturnsNonNull>(mmap, "reifiedSafeAs>(mmap)") + reifiedSafeAsReturnsNonNull>(hashMap, "reifiedSafeAs>(hashMap)") + + val entry = ME() as Any + val mentry = MME() + + hashMap[""] = "" + val hashMapEntry = hashMap.entries.first() + + reifiedSafeAsReturnsNull>(entry, "reifiedSafeAs>(entry)") + reifiedSafeAsReturnsNonNull>(mentry, "reifiedSafeAs>(mentry)") + reifiedSafeAsReturnsNonNull>(hashMapEntry, "reifiedSafeAs>(hashMapEntry)") + + reifiedSafeAsReturnsNull>(null, "reifiedSafeAs>(null)") + reifiedSafeAsReturnsNull>(null, "reifiedSafeAs>(null)") + reifiedSafeAsReturnsNull>(null, "reifiedSafeAs>(null)") + reifiedSafeAsReturnsNull>(null, "reifiedSafeAs>(null)") + reifiedSafeAsReturnsNull>(null, "reifiedSafeAs>(null)") + reifiedSafeAsReturnsNull>(null, "reifiedSafeAs>(null)") + reifiedSafeAsReturnsNull>(null, "reifiedSafeAs>(null)") + reifiedSafeAsReturnsNull>(null, "reifiedSafeAs>(null)") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/safeAsWithMutable.kt b/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/safeAsWithMutable.kt new file mode 100644 index 00000000000..58113095c09 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/safeAsWithMutable.kt @@ -0,0 +1,140 @@ +// WITH_RUNTIME + +class Itr : Iterator by ArrayList().iterator() +class MItr : MutableIterator by ArrayList().iterator() +class LItr : ListIterator by ArrayList().listIterator() +class MLItr : MutableListIterator by ArrayList().listIterator() + +class It : Iterable by ArrayList() +class MIt : MutableIterable by ArrayList() +class C : Collection by ArrayList() +class MC : MutableCollection by ArrayList() +class L : List by ArrayList() +class ML : MutableList by ArrayList() +class S : Set by HashSet() +class MS : MutableSet by HashSet() + +class M : Map by HashMap() +class MM : MutableMap by HashMap() + +class ME : Map.Entry { + override val key: String get() = throw UnsupportedOperationException() + override val value: String get() = throw UnsupportedOperationException() +} + +class MME : MutableMap.MutableEntry { + override val key: String get() = throw UnsupportedOperationException() + override val value: String get() = throw UnsupportedOperationException() + override fun setValue(value: String): String = throw UnsupportedOperationException() +} + +fun assert(condition: Boolean, message: () -> String) { if (!condition) throw AssertionError(message())} + + +inline fun safeAsReturnsNull(operation: String, cast: () -> Any?) { + try { + val x = cast() + assert(x == null) { "$operation: should return null, got $x" } + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +inline fun safeAsReturnsNonNull(operation: String, cast: () -> Any?) { + try { + val x = cast() + assert(x != null) { "$operation: should return non-null" } + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +fun box(): String { + val itr = Itr() as Any + val mitr = MItr() + + safeAsReturnsNull("itr as? MutableIterator") { itr as? MutableIterator<*> } + safeAsReturnsNonNull("mitr as? MutableIterator") { mitr as? MutableIterator<*> } + + val litr = LItr() as Any + val mlitr = MLItr() + + safeAsReturnsNull("litr as? MutableIterator") { litr as? MutableIterator<*> } + safeAsReturnsNull("litr as? MutableListIterator") { litr as? MutableListIterator<*> } + safeAsReturnsNonNull("mlitr as? MutableIterator") { mlitr as? MutableIterator<*> } + safeAsReturnsNonNull("mlitr as? MutableListIterator") { mlitr as? MutableListIterator<*> } + + val it = It() as Any + val mit = MIt() + val arrayList = ArrayList() + + safeAsReturnsNull("it as? MutableIterable") { it as? MutableIterable<*> } + safeAsReturnsNonNull("mit as? MutableIterable") { mit as? MutableIterable<*> } + safeAsReturnsNonNull("arrayList as? MutableIterable") { arrayList as? MutableIterable<*> } + + val coll = C() as Any + val mcoll = MC() + + safeAsReturnsNull("coll as? MutableIterable") { coll as? MutableIterable<*> } + safeAsReturnsNull("coll as? MutableCollection") { coll as? MutableCollection<*> } + safeAsReturnsNonNull("mcoll as? MutableIterable") { mcoll as? MutableIterable<*> } + safeAsReturnsNonNull("mcoll as? MutableCollection") { mcoll as? MutableCollection<*> } + safeAsReturnsNonNull("arrayList as? MutableCollection") { arrayList as? MutableCollection<*> } + + val list = L() as Any + val mlist = ML() + + safeAsReturnsNull("list as? MutableIterable") { list as? MutableIterable<*> } + safeAsReturnsNull("list as? MutableCollection") { list as? MutableCollection<*> } + safeAsReturnsNull("list as? MutableList") { list as? MutableList<*> } + safeAsReturnsNonNull("mlist as? MutableIterable") { mlist as? MutableIterable<*> } + safeAsReturnsNonNull("mlist as? MutableCollection") { mlist as? MutableCollection<*> } + safeAsReturnsNonNull("mlist as? MutableList") { mlist as? MutableList<*> } + + val set = S() as Any + val mset = MS() + val hashSet = HashSet() + + safeAsReturnsNull("set as? MutableIterable") { set as? MutableIterable<*> } + safeAsReturnsNull("set as? MutableCollection") { set as? MutableCollection<*> } + safeAsReturnsNull("set as? MutableSet") { set as? MutableSet<*> } + safeAsReturnsNonNull("mset as? MutableIterable") { mset as? MutableIterable<*> } + safeAsReturnsNonNull("mset as? MutableCollection") { mset as? MutableCollection<*> } + safeAsReturnsNonNull("mset as? MutableSet") { mset as? MutableSet<*> } + safeAsReturnsNonNull("hashSet as? MutableSet") { hashSet as? MutableSet<*> } + + val map = M() as Any + val mmap = MM() + val hashMap = HashMap() + + safeAsReturnsNull("map as? MutableMap") { map as? MutableMap<*, *> } + safeAsReturnsNonNull("mmap as? MutableMap") { mmap as? MutableMap<*, *> } + safeAsReturnsNonNull("hashMap as? MutableMap") { hashMap as? MutableMap<*, *> } + + val entry = ME() as Any + val mentry = MME() + + safeAsReturnsNull("entry as? MutableMap.MutableEntry") { entry as? MutableMap.MutableEntry<*, *> } + safeAsReturnsNonNull("mentry as? MutableMap.MutableEntry") { mentry as? MutableMap.MutableEntry<*, *> } + + hashMap[""] = "" + val hashMapEntry = hashMap.entries.first() + + safeAsReturnsNonNull("hashMapEntry as? MutableMap.MutableEntry") { hashMapEntry as? MutableMap.MutableEntry<*, *> } + + safeAsReturnsNull("null as? MutableIterator") { null as? MutableIterator<*> } + safeAsReturnsNull("null as? MutableListIterator") { null as? MutableListIterator<*> } + safeAsReturnsNull("null as? MutableIterable") { null as? MutableIterable<*> } + safeAsReturnsNull("null as? MutableCollection") { null as? MutableCollection<*> } + safeAsReturnsNull("null as? MutableList") { null as? MutableList<*> } + safeAsReturnsNull("null as? MutableSet") { null as? MutableSet<*> } + safeAsReturnsNull("null as? MutableMap") { null as? MutableMap<*, *> } + safeAsReturnsNull("null as? MutableMap.MutableEntry") { null as? MutableMap.MutableEntry<*, *> } + + safeAsReturnsNull("mlist as? MutableSet") { mlist as? MutableSet<*> } + safeAsReturnsNull("mlist as? MutableIterator") { mlist as? MutableIterator<*> } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/weirdMutableCasts.kt b/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/weirdMutableCasts.kt new file mode 100644 index 00000000000..137035866b1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/mutableCollections/weirdMutableCasts.kt @@ -0,0 +1,143 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun unsupported(): Nothing = throw UnsupportedOperationException() + +class Weird : Iterator, MutableIterable, MutableMap.MutableEntry { + override fun next(): String = unsupported() + override fun hasNext(): Boolean = unsupported() + override val key: String get() = unsupported() + override val value: String get() = unsupported() + override fun setValue(value: String): String = unsupported() + override fun iterator(): MutableIterator = unsupported() +} + +inline fun asFailsWithCCE(operation: String, cast: () -> Unit) { + try { + cast() + } + catch (e: java.lang.ClassCastException) { + return + } + catch (e: Throwable) { + throw AssertionError("$operation: should throw ClassCastException, got $e") + } + throw AssertionError("$operation: should throw ClassCastException, no exception thrown") +} + +inline fun asSucceeds(operation: String, cast: () -> Unit) { + try { + cast() + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +inline fun safeAsReturnsNull(operation: String, cast: () -> Any?) { + try { + val x = cast() + assert(x == null) { "$operation: should return null, got $x" } + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +inline fun safeAsReturnsNonNull(operation: String, cast: () -> Any?) { + try { + val x = cast() + assert(x != null) { "$operation: should return non-null" } + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +inline fun reifiedIs(x: Any): Boolean = x is T + +inline fun reifiedIsNot(x: Any): Boolean = x !is T + +inline fun reifiedAsSucceeds(x: Any, operation: String) { + try { + x as T + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } +} + +inline fun reifiedAsFailsWithCCE(x: Any, operation: String) { + try { + x as T + } + catch (e: java.lang.ClassCastException) { + return + } + catch (e: Throwable) { + throw AssertionError("$operation: should throw ClassCastException, got $e") + } + throw AssertionError("$operation: should fail with CCE, no exception thrown") +} + +inline fun reifiedSafeAsReturnsNonNull(x: Any?, operation: String) { + val y = try { + x as? T + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } + if (y == null) { + throw AssertionError("$operation: should return non-null, got null") + } +} + +inline fun reifiedSafeAsReturnsNull(x: Any?, operation: String) { + val y = try { + x as? T + } + catch (e: Throwable) { + throw AssertionError("$operation: should not throw exceptions, got $e") + } + if (y != null) { + throw AssertionError("$operation: should return null, got $y") + } +} + +fun box(): String { + val w: Any = Weird() + + assert(w is Iterator<*>) { "w is Iterator<*>" } + assert(w !is MutableIterator<*>) { "w !is MutableIterator<*>" } + assert(w is MutableIterable<*>) { "w is MutableIterable<*>" } + assert(w is MutableMap.MutableEntry<*, *>) { "w is MutableMap.MutableEntry<*, *>" } + + asSucceeds("w as Iterator<*>") { w as Iterator<*> } + asFailsWithCCE("w as MutableIterator<*>") { w as MutableIterator<*> } + asSucceeds("w as MutableIterable<*>") { w as MutableIterable<*> } + asSucceeds("w as MutableMap.MutableEntry<*, *>") { w as MutableMap.MutableEntry<*, *> } + + safeAsReturnsNonNull("w as Iterator<*>") { w as? Iterator<*> } + safeAsReturnsNull("w as? MutableIterator<*>") { w as? MutableIterator<*> } + safeAsReturnsNonNull("w as? MutableIterable<*>") { w as? MutableIterable<*> } + safeAsReturnsNonNull("w as? MutableMap.MutableEntry<*, *>") { w as? MutableMap.MutableEntry<*, *> } + + assert(reifiedIs>(w)) { "reifiedIs>(w)" } + assert(reifiedIsNot>(w)) { "reifiedIsNot>(w)" } + assert(reifiedIs>(w)) { "reifiedIs>(w)" } + assert(reifiedIs>(w)) { "reifiedIs>(w)" } + + reifiedAsSucceeds>(w, "reified w as Iterator<*>") + reifiedAsFailsWithCCE>(w, "reified w as MutableIterator<*>") + reifiedAsSucceeds>(w, "reified w as MutableIterable<*>") + reifiedAsSucceeds>(w, "reified w as MutableMap.MutableEntry<*, *>") + + reifiedSafeAsReturnsNonNull>(w, "reified w as? Iterator<*>") + reifiedSafeAsReturnsNull>(w, "reified w as? MutableIterator<*>") + reifiedSafeAsReturnsNonNull>(w, "reified w as? MutableIterable<*>") + reifiedSafeAsReturnsNonNull>(w, "reified w as? MutableMap.MutableEntry<*, *>") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/notIs.kt b/backend.native/tests/external/codegen/blackbox/casts/notIs.kt new file mode 100644 index 00000000000..5e784474bb9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/notIs.kt @@ -0,0 +1,11 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun foo(x: Any) = x !is Runnable + +fun box(): String { + val r = object : Runnable { + override fun run() {} + } + return if (!foo(r) && foo(42)) "OK" else "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/unitAsAny.kt b/backend.native/tests/external/codegen/blackbox/casts/unitAsAny.kt new file mode 100644 index 00000000000..da598959fe0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/unitAsAny.kt @@ -0,0 +1,11 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun println(s: String) { +} + +fun box(): String { + val x = println(":Hi!") as Any + if (x != Unit) return "Fail: $x" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/unitAsInt.kt b/backend.native/tests/external/codegen/blackbox/casts/unitAsInt.kt new file mode 100644 index 00000000000..5e0ab81ea20 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/unitAsInt.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun foo() {} + +fun box(): String { + try { + foo() as Int? + } + catch (e: ClassCastException) { + return "OK" + } + catch (e: Throwable) { + return "Fail: ClassCastException should have been thrown, but was instead ${e.javaClass.getName()}: ${e.message}" + } + + return "Fail: no exception was thrown" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/unitAsSafeAny.kt b/backend.native/tests/external/codegen/blackbox/casts/unitAsSafeAny.kt new file mode 100644 index 00000000000..228e5aeaba9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/unitAsSafeAny.kt @@ -0,0 +1,11 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun println(s: String) { +} + +fun box(): String { + val x = println(":Hi!") as? Any + if (x != Unit) return "Fail: $x" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/casts/unitNullableCast.kt b/backend.native/tests/external/codegen/blackbox/casts/unitNullableCast.kt new file mode 100644 index 00000000000..c0f644e88a5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/casts/unitNullableCast.kt @@ -0,0 +1,7 @@ +fun foo() {} + +fun bar(): Int? = foo() as? Int + +fun box(): String { + return if (bar() == null) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classLiteral/bound/javaIntrinsicWithSideEffect.kt b/backend.native/tests/external/codegen/blackbox/classLiteral/bound/javaIntrinsicWithSideEffect.kt new file mode 100644 index 00000000000..52190d0f390 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classLiteral/bound/javaIntrinsicWithSideEffect.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String { + var x = 42 + val k = (x++)::class.java + if (k != Int::class.java) return "Fail 1: $k" + if (x != 43) return "Fail 2: $x (side effect should have taken place)" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classLiteral/bound/primitives.kt b/backend.native/tests/external/codegen/blackbox/classLiteral/bound/primitives.kt new file mode 100644 index 00000000000..16739b170fe --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classLiteral/bound/primitives.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + assertEquals(true::class, Boolean::class) + assertEquals(42.toByte()::class, Byte::class) + assertEquals('z'::class, Char::class) + assertEquals(3.14::class, Double::class) + assertEquals(2.72f::class, Float::class) + assertEquals(42::class, Int::class) + assertEquals(42L::class, Long::class) + assertEquals(42.toShort()::class, Short::class) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classLiteral/bound/sideEffect.kt b/backend.native/tests/external/codegen/blackbox/classLiteral/bound/sideEffect.kt new file mode 100644 index 00000000000..a1fee693ce7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classLiteral/bound/sideEffect.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + var x = 42 + + val k1 = (x++)::class + if (k1 != Int::class) return "Fail 1: $k1" + if (x != 43) return "Fail 2: $x" + + val k2 = { x *= 2; x }()::class + // Note that k2 is the class of the wrapper type java.lang.Integer + if (k2 != Integer::class) return "Fail 3: $k2" + if (x != 86) return "Fail 4: $x" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classLiteral/bound/simple.kt b/backend.native/tests/external/codegen/blackbox/classLiteral/bound/simple.kt new file mode 100644 index 00000000000..f6de756700b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classLiteral/bound/simple.kt @@ -0,0 +1,8 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + val x: CharSequence = "" + val klass = x::class + return if (klass == String::class) "OK" else "Fail: $klass" +} diff --git a/backend.native/tests/external/codegen/blackbox/classLiteral/java/java.kt b/backend.native/tests/external/codegen/blackbox/classLiteral/java/java.kt new file mode 100644 index 00000000000..64f95e8ad6d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classLiteral/java/java.kt @@ -0,0 +1,63 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.reflect.KClass + +fun checkPrimitive(clazz: Class<*>, expected: String) { + assert (clazz!!.canonicalName == expected) { + "clazz name: ${clazz.canonicalName}" + } +} + +fun checkPrimitive(kClass: KClass<*>, expected: String) { + checkPrimitive(kClass.java, expected) +} + +fun checkObject(clazz: Class<*>, expected: String) { + assert (clazz.canonicalName == "$expected") { + "clazz should be object, but found: ${clazz!!.canonicalName}" + } +} + +fun checkObject(kClass: KClass<*>, expected: String) { + checkObject(kClass.java, expected) +} + +fun box(): String { + checkPrimitive(Boolean::class.java, "boolean") + checkPrimitive(Boolean::class, "boolean") + + checkPrimitive(Char::class.java, "char") + checkPrimitive(Char::class, "char") + + checkPrimitive(Byte::class.java, "byte") + checkPrimitive(Byte::class, "byte") + + checkPrimitive(Short::class.java, "short") + checkPrimitive(Short::class, "short") + + checkPrimitive(Int::class.java, "int") + checkPrimitive(Int::class, "int") + + checkPrimitive(Float::class.java, "float") + checkPrimitive(Float::class, "float") + + checkPrimitive(Long::class.java, "long") + checkPrimitive(Long::class, "long") + + checkPrimitive(Double::class.java, "double") + checkPrimitive(Double::class, "double") + + checkObject(String::class.java, "java.lang.String") + checkObject(String::class, "java.lang.String") + + checkObject(Nothing::class.java, "java.lang.Void") + checkObject(Nothing::class, "java.lang.Void") + + checkObject(java.lang.Void::class.java, "java.lang.Void") + checkObject(java.lang.Void::class, "java.lang.Void") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classLiteral/java/javaObjectType.kt b/backend.native/tests/external/codegen/blackbox/classLiteral/java/javaObjectType.kt new file mode 100644 index 00000000000..b64ff4634f6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classLiteral/java/javaObjectType.kt @@ -0,0 +1,53 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.reflect.KClass + +fun check(clazz: Class<*>?, expected: String) { + assert (clazz!!.canonicalName == expected) { + "clazz name: ${clazz.canonicalName}" + } +} + +fun check(kClass: KClass<*>, expected: String) { + check(kClass.javaObjectType, expected) +} + +fun box(): String { + check(Boolean::class.javaObjectType, "java.lang.Boolean") + check(Boolean::class, "java.lang.Boolean") + + check(Char::class.javaObjectType, "java.lang.Character") + check(Char::class, "java.lang.Character") + + check(Byte::class.javaObjectType, "java.lang.Byte") + check(Byte::class, "java.lang.Byte") + + check(Short::class.javaObjectType, "java.lang.Short") + check(Short::class, "java.lang.Short") + + check(Int::class.javaObjectType, "java.lang.Integer") + check(Int::class, "java.lang.Integer") + + check(Float::class.javaObjectType, "java.lang.Float") + check(Float::class, "java.lang.Float") + + check(Long::class.javaObjectType, "java.lang.Long") + check(Long::class, "java.lang.Long") + + check(Double::class.javaObjectType, "java.lang.Double") + check(Double::class, "java.lang.Double") + + check(String::class.javaObjectType, "java.lang.String") + check(String::class, "java.lang.String") + + check(Nothing::class.javaObjectType, "java.lang.Void") + check(Nothing::class, "java.lang.Void") + + check(Void::class.javaObjectType, "java.lang.Void") + check(Void::class, "java.lang.Void") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classLiteral/java/javaObjectTypeReified.kt b/backend.native/tests/external/codegen/blackbox/classLiteral/java/javaObjectTypeReified.kt new file mode 100644 index 00000000000..02fc734f52a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classLiteral/java/javaObjectTypeReified.kt @@ -0,0 +1,27 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +inline fun check(expected: String) { + val clazz = T::class.javaObjectType!! + assert (clazz.canonicalName == "java.lang.$expected") { + "clazz name: ${clazz.canonicalName}" + } +} + +fun box(): String { + check("Boolean") + check("Character") + check("Byte") + check("Short") + check("Integer") + check("Float") + check("Long") + check("Double") + + check("String") + check("Void") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classLiteral/java/javaPrimitiveType.kt b/backend.native/tests/external/codegen/blackbox/classLiteral/java/javaPrimitiveType.kt new file mode 100644 index 00000000000..c413aee39c2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classLiteral/java/javaPrimitiveType.kt @@ -0,0 +1,63 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.reflect.KClass + +fun check(clazz: Class<*>?, expected: String) { + assert (clazz!!.canonicalName == expected) { + "clazz name: ${clazz.canonicalName}" + } +} + +fun check(kClass: KClass<*>, expected: String) { + check(kClass.javaPrimitiveType, expected) +} + +fun checkNull(clazz: Class<*>?) { + assert (clazz == null) { + "clazz should be null: ${clazz!!.canonicalName}" + } +} + +fun checkNull(kClass: KClass<*>) { + checkNull(kClass.javaPrimitiveType) +} + +fun box(): String { + check(Boolean::class.javaPrimitiveType, "boolean") + check(Boolean::class, "boolean") + + check(Char::class.javaPrimitiveType, "char") + check(Char::class, "char") + + check(Byte::class.javaPrimitiveType, "byte") + check(Byte::class, "byte") + + check(Short::class.javaPrimitiveType, "short") + check(Short::class, "short") + + check(Int::class.javaPrimitiveType, "int") + check(Int::class, "int") + + check(Float::class.javaPrimitiveType, "float") + check(Float::class, "float") + + check(Long::class.javaPrimitiveType, "long") + check(Long::class, "long") + + check(Double::class.javaPrimitiveType, "double") + check(Double::class, "double") + + checkNull(String::class.javaPrimitiveType) + checkNull(String::class) + + checkNull(Nothing::class.javaPrimitiveType) + checkNull(Nothing::class) + + checkNull(Void::class.javaPrimitiveType) + checkNull(Void::class) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classLiteral/java/javaPrimitiveTypeReified.kt b/backend.native/tests/external/codegen/blackbox/classLiteral/java/javaPrimitiveTypeReified.kt new file mode 100644 index 00000000000..c9b71561637 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classLiteral/java/javaPrimitiveTypeReified.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +inline fun check(expected: String) { + val clazz = T::class.javaPrimitiveType!! + assert (clazz.canonicalName == expected) { + "clazz name: ${clazz.canonicalName}" + } +} + +inline fun checkNull() { + val clazz = T::class.javaPrimitiveType + assert (clazz == null) { + "clazz should be null: ${clazz!!.canonicalName}" + } +} + +fun box(): String { + check("boolean") + check("char") + check("byte") + check("short") + check("int") + check("float") + check("long") + check("double") + + checkNull() + checkNull() + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classLiteral/java/javaReified.kt b/backend.native/tests/external/codegen/blackbox/classLiteral/java/javaReified.kt new file mode 100644 index 00000000000..e6e4821d9aa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classLiteral/java/javaReified.kt @@ -0,0 +1,27 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +inline fun check(expected: String) { + val clazz = T::class.java!! + assert (clazz.canonicalName == "java.lang.$expected") { + "clazz name: ${clazz.canonicalName}" + } +} + +fun box(): String { + check("Boolean") + check("Character") + check("Byte") + check("Short") + check("Integer") + check("Float") + check("Long") + check("Double") + + check("String") + check("Void") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classLiteral/java/kt11943.kt b/backend.native/tests/external/codegen/blackbox/classLiteral/java/kt11943.kt new file mode 100644 index 00000000000..31b37df66c9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classLiteral/java/kt11943.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.reflect.KClass + +val > T.myjava1: Class<*> + get() = java + +val > T.myjava2: Class + get() = java + +class O +class K + +fun box(): String = + O::class.myjava1.getSimpleName() + K::class.myjava2.getSimpleName() + diff --git a/backend.native/tests/external/codegen/blackbox/classLiteral/java/objectSuperConstructorCall.kt b/backend.native/tests/external/codegen/blackbox/classLiteral/java/objectSuperConstructorCall.kt new file mode 100644 index 00000000000..cfbf4d7f08b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classLiteral/java/objectSuperConstructorCall.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +abstract class S(val klass: Class) { + val result = klass.simpleName +} + +object OK : S(OK::class.java) + +class C { + companion object Companion : S(Companion::class.java) +} + +fun box(): String { + assertEquals("Companion", C.Companion.result) + return OK.result +} diff --git a/backend.native/tests/external/codegen/blackbox/classLiteral/primitiveKClassEquality.kt b/backend.native/tests/external/codegen/blackbox/classLiteral/primitiveKClassEquality.kt new file mode 100644 index 00000000000..53d9f7d980b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classLiteral/primitiveKClassEquality.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals +import kotlin.test.assertFalse + +fun box(): String { + val x = Int::class.javaPrimitiveType!!.kotlin + val y = Int::class.javaObjectType.kotlin + + assertEquals(x, y) + assertEquals(x.hashCode(), y.hashCode()) + assertFalse(x === y) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/boxPrimitiveTypeInClinitOfClassObject.kt b/backend.native/tests/external/codegen/blackbox/classes/boxPrimitiveTypeInClinitOfClassObject.kt new file mode 100644 index 00000000000..497167d4be6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/boxPrimitiveTypeInClinitOfClassObject.kt @@ -0,0 +1,31 @@ +class A { + companion object { + var xi = 0 + var xin : Int? = 0 + var xinn : Int? = null + + var xl = 0.toLong() + var xln : Long? = 0.toLong() + var xlnn : Long? = null + + var xb = 0.toByte() + var xbn : Byte? = 0.toByte() + var xbnn : Byte? = null + + var xf = 0.toFloat() + var xfn : Float? = 0.toFloat() + var xfnn : Float? = null + + var xd = 0.toDouble() + var xdn : Double? = 0.toDouble() + var xdnn : Double? = null + + var xs = 0.toShort() + var xsn : Short? = 0.toShort() + var xsnn : Short? = null + } +} + +fun box() : String { + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/classCompanionInitializationWithJava.kt b/backend.native/tests/external/codegen/blackbox/classes/classCompanionInitializationWithJava.kt new file mode 100644 index 00000000000..814f87dbdb5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/classCompanionInitializationWithJava.kt @@ -0,0 +1,33 @@ +// TARGET_BACKEND: JVM +// FILE: CompanionInitialization.java + +public class CompanionInitialization { + + public static Object getCompanion() { + return ConcreteWithStatic.Companion; + } + +} + +// FILE: CompanionInitialization.kt + +interface IStatic + +open class Static(x: IStatic) { + fun doSth() { + } +} + +class ConcreteWithStatic : IStatic { + companion object : Static(ConcreteWithStatic()) +} + +fun box(): String { + ConcreteWithStatic.doSth() + + val companion: Any? = CompanionInitialization.getCompanion() + if (companion == null) return "fail 1" + if (companion != ConcreteWithStatic) return "fail 2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/classNamedAsOldPackageFacade.kt b/backend.native/tests/external/codegen/blackbox/classes/classNamedAsOldPackageFacade.kt new file mode 100644 index 00000000000..24c2efdc564 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/classNamedAsOldPackageFacade.kt @@ -0,0 +1,7 @@ +package test + +class TestPackage { + val OK = "OK" +} + +fun box(): String = TestPackage().OK \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/classes/classObject.kt b/backend.native/tests/external/codegen/blackbox/classes/classObject.kt new file mode 100644 index 00000000000..c8da87c8a7f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/classObject.kt @@ -0,0 +1,11 @@ +class C() { + companion object { + fun create() = C() + } +} + +fun box(): String { + val c = C.create() + return if (c is C) "OK" else "fail" +} + diff --git a/backend.native/tests/external/codegen/blackbox/classes/classObjectAsExtensionReceiver.kt b/backend.native/tests/external/codegen/blackbox/classes/classObjectAsExtensionReceiver.kt new file mode 100644 index 00000000000..886dbdf8364 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/classObjectAsExtensionReceiver.kt @@ -0,0 +1,7 @@ +fun Any.foo() = 1 + +class A { + companion object +} + +fun box() = if (A.foo() == 1) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/classes/classObjectAsStaticInitializer.kt b/backend.native/tests/external/codegen/blackbox/classes/classObjectAsStaticInitializer.kt new file mode 100644 index 00000000000..d9175424f8e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/classObjectAsStaticInitializer.kt @@ -0,0 +1,19 @@ +var global = 0; + +class C { + companion object { + init { + global = 1; + } + } +} + +fun box(): String { + if (global != 0) { + return "fail1: global = $global" + } + + val c = C() + if (global == 1) return "OK" else return "fail2: global = $global" +} + diff --git a/backend.native/tests/external/codegen/blackbox/classes/classObjectField.kt b/backend.native/tests/external/codegen/blackbox/classes/classObjectField.kt new file mode 100644 index 00000000000..f23073c6e89 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/classObjectField.kt @@ -0,0 +1,7 @@ +class A() { + companion object { + val value = 10 + } +} + +fun box() = if (A.value == 10) "OK" else "Fail ${A.value}" diff --git a/backend.native/tests/external/codegen/blackbox/classes/classObjectInTrait.kt b/backend.native/tests/external/codegen/blackbox/classes/classObjectInTrait.kt new file mode 100644 index 00000000000..e34f5622a3e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/classObjectInTrait.kt @@ -0,0 +1,12 @@ +// EA-38323 - Illegal field modifiers in class: classObject field in C must be static and final + +interface C { + companion object { + public val FOO: String = "OK" + } +} + +fun box(): String { + return C.FOO +} + diff --git a/backend.native/tests/external/codegen/blackbox/classes/classObjectNotOfEnum.kt b/backend.native/tests/external/codegen/blackbox/classes/classObjectNotOfEnum.kt new file mode 100644 index 00000000000..e2a775320cd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/classObjectNotOfEnum.kt @@ -0,0 +1,8 @@ +class A { + companion object { + fun values() = "O" + fun valueOf() = "K" + } +} + +fun box() = A.values() + A.valueOf() diff --git a/backend.native/tests/external/codegen/blackbox/classes/classObjectToString.kt b/backend.native/tests/external/codegen/blackbox/classes/classObjectToString.kt new file mode 100644 index 00000000000..901b77a1bad --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/classObjectToString.kt @@ -0,0 +1,9 @@ +// TODO: Enable for JS when it supports Java class library. +// IGNORE_BACKEND: JS, NATIVE +class SomeClass { companion object } + +fun box() = + if ((SomeClass.toString() as java.lang.String).matches("SomeClass\\\$Companion@[0-9a-fA-F]+")) + "OK" + else + "Fail: $SomeClass" diff --git a/backend.native/tests/external/codegen/blackbox/classes/classObjectWithPrivateGenericMember.kt b/backend.native/tests/external/codegen/blackbox/classes/classObjectWithPrivateGenericMember.kt new file mode 100644 index 00000000000..bb7b150238f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/classObjectWithPrivateGenericMember.kt @@ -0,0 +1,15 @@ +class C() { + companion object { + private fun create() = C() + } + + class ZZZ { + val c = C.create() + } +} + +fun box(): String { + C.ZZZ().c + return "OK" +} + diff --git a/backend.native/tests/external/codegen/blackbox/classes/classObjectsWithParentClasses.kt b/backend.native/tests/external/codegen/blackbox/classes/classObjectsWithParentClasses.kt new file mode 100644 index 00000000000..668619e3032 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/classObjectsWithParentClasses.kt @@ -0,0 +1,12 @@ +open class Test { + companion object { + fun testStatic(ic: InnerClass): NotInnerClass = NotInnerClass(ic.value) + } + + fun test(): InnerClass = InnerClass(150) + + inner open class InnerClass(val value: Int) + open class NotInnerClass(val value: Int) +} + +fun box() = if (Test.testStatic(Test().test()).value == 150) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/classes/defaultObjectSameNamesAsInOuter.kt b/backend.native/tests/external/codegen/blackbox/classes/defaultObjectSameNamesAsInOuter.kt new file mode 100644 index 00000000000..8332b83ef41 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/defaultObjectSameNamesAsInOuter.kt @@ -0,0 +1,18 @@ +class A { + private val p: Int + get() = 4 + + companion object B { + val p: Int + get() = 6 + } + + fun a() = p + B.p +} + + +fun box(): String { + if (A().a() != 10) return "Fail" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/delegation2.kt b/backend.native/tests/external/codegen/blackbox/classes/delegation2.kt new file mode 100644 index 00000000000..81b8b0fb47e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/delegation2.kt @@ -0,0 +1,24 @@ +interface Trait1 { + fun foo() : String +} + +interface Trait2 { + fun bar() : String +} + +class T1 : Trait1{ + override fun foo() = "aaa" +} + +class T2 : Trait2{ + override fun bar() = "bbb" +} + +class C(a:Trait1, b:Trait2) : Trait1 by a, Trait2 by b + +fun box() : String { + val c = C(T1(),T2()) + if(c.foo() != "aaa") return "fail" + if(c.bar() != "bbb") return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/delegation3.kt b/backend.native/tests/external/codegen/blackbox/classes/delegation3.kt new file mode 100644 index 00000000000..fd4f07800a2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/delegation3.kt @@ -0,0 +1,35 @@ +interface One { + public open fun foo() : Int + public open fun faz() : Int = 10 +} +interface Two { + public open fun foo() : Int + public open fun quux() : Int = 100 +} + +class OneImpl : One { + public override fun foo() = 1 +} +class TwoImpl : Two { + public override fun foo() = 2 +} + +class Test2(a : One, b : Two) : Two by b, One by a { + public override fun foo() = 0 +} + +fun box() : String { + var t2 = Test2(OneImpl(), TwoImpl()) + if (t2.foo() != 0) + return "Fail #1" + if (t2.faz() != 10) + return "Fail #2" + if (t2.quux() != 100) + return "Fail #3" + if (t2 !is One) + return "Fail #4" + if (t2 !is Two) + return "Fail #5" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/delegation4.kt b/backend.native/tests/external/codegen/blackbox/classes/delegation4.kt new file mode 100644 index 00000000000..7a9c9449e58 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/delegation4.kt @@ -0,0 +1,28 @@ +interface First { + public open fun foo() : Int +} + +interface Second : First { + public open fun bar() : Int +} + +class Impl : Second { + public override fun foo() = 1 + public override fun bar() = 2 +} + +class Test(s : Second) : Second by s {} + +fun box() : String { + var t = Test(Impl()) + if (t.foo() != 1) + return "Fail #1" + if (t.bar() != 2) + return "Fail #2" + if (t !is First) + return "Fail #3" + if (t !is Second) + return "Fail #4" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/delegationGenericArg.kt b/backend.native/tests/external/codegen/blackbox/classes/delegationGenericArg.kt new file mode 100644 index 00000000000..f298e834f79 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/delegationGenericArg.kt @@ -0,0 +1,12 @@ +interface A { + fun foo(t: T): String +} + +class Derived(a: A) : A by a + +fun box(): String { + val o = object : A { + override fun foo(t: Int) = if (t == 42) "OK" else "Fail $t" + } + return Derived(o).foo(42) +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/delegationGenericArgUpperBound.kt b/backend.native/tests/external/codegen/blackbox/classes/delegationGenericArgUpperBound.kt new file mode 100644 index 00000000000..72e541b7f3b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/delegationGenericArgUpperBound.kt @@ -0,0 +1,12 @@ +interface A { + fun foo(t: T): String +} + +class Derived(a: A) : A by a + +fun box(): String { + val o = object : A { + override fun foo(t: Int) = if (t == 42) "OK" else "Fail $t" + } + return Derived(o).foo(42) +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/delegationGenericLongArg.kt b/backend.native/tests/external/codegen/blackbox/classes/delegationGenericLongArg.kt new file mode 100644 index 00000000000..8bd117f9fa1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/delegationGenericLongArg.kt @@ -0,0 +1,12 @@ +interface A { + fun foo(t: T, u: U): String +} + +class Derived(a: A) : A by a + +fun box(): String { + val o = object : A { + override fun foo(t: Long, u: Int) = if (t == u.toLong()) "OK" else "Fail $t $u" + } + return Derived(o).foo(42, 42) +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/delegationJava.kt b/backend.native/tests/external/codegen/blackbox/classes/delegationJava.kt new file mode 100644 index 00000000000..f4ad18d3b22 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/delegationJava.kt @@ -0,0 +1,16 @@ +// Enable for JS when it supports Java class library. +// IGNORE_BACKEND: JS, NATIVE + +class TestJava(r : Runnable) : Runnable by r {} +class TestRunnable() : Runnable { + public override fun run() = System.out.println("foobar") +} + +fun box() : String { + var del = TestJava(TestRunnable()) + del.run() + if (del !is Runnable) + return "Fail #1" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/delegationMethodsWithArgs.kt b/backend.native/tests/external/codegen/blackbox/classes/delegationMethodsWithArgs.kt new file mode 100644 index 00000000000..a8c0e37230c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/delegationMethodsWithArgs.kt @@ -0,0 +1,34 @@ +package test + +interface TextField { + fun getText(): String +} + +interface InputTextField : TextField { + fun setText(text: String) +} + +interface MooableTextField : InputTextField { + fun moo(a: Int, b: Int, c: Int): Int +} + +class SimpleTextField : MooableTextField { + private var text2 = "" + override fun getText() = text2 + override fun setText(text: String) { + this.text2 = text + } + override fun moo(a: Int, b: Int, c: Int) = a + b + c +} + +class TextFieldWrapper(textField: MooableTextField) : MooableTextField by textField + +fun box() : String { + val textField = TextFieldWrapper(SimpleTextField()) + textField.setText("hello world!") + + if (!textField.getText().equals("hello world!")) return "FAIL #!1" + if (textField.moo(1,2,3) != 6) return "FAIL #2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/exceptionConstructor.kt b/backend.native/tests/external/codegen/blackbox/classes/exceptionConstructor.kt new file mode 100644 index 00000000000..30da7cb5b09 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/exceptionConstructor.kt @@ -0,0 +1,7 @@ +class GameError(msg: String): Exception(msg) { +} + +fun box(): String { + val e = GameError("foo") + return if (e.message == "foo") "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/extensionOnNamedClassObject.kt b/backend.native/tests/external/codegen/blackbox/classes/extensionOnNamedClassObject.kt new file mode 100644 index 00000000000..dd3efea880b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/extensionOnNamedClassObject.kt @@ -0,0 +1,12 @@ +class C() { + companion object Foo +} + +fun C.Foo.create() = 3 + +fun box(): String { + val c1 = C.Foo.create() + val c2 = C.create() + return if (c1 == 3 && c2 == 3) "OK" else "fail" +} + diff --git a/backend.native/tests/external/codegen/blackbox/classes/funDelegation.kt b/backend.native/tests/external/codegen/blackbox/classes/funDelegation.kt new file mode 100644 index 00000000000..2a75f698109 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/funDelegation.kt @@ -0,0 +1,17 @@ +open class Base() { + fun n(n : Int) : Int = n + 1 +} + +interface Abstract {} + +class Derived1() : Base(), Abstract {} +class Derived2() : Abstract, Base() {} + +fun test(s : Base) : Boolean = s.n(238) == 239 + +fun box() : String { + if (!test(Base())) return "Fail #1" + if (!test(Derived1())) return "Fail #2" + if (!test(Derived2())) return "Fail #3" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/implementComparableInSubclass.kt b/backend.native/tests/external/codegen/blackbox/classes/implementComparableInSubclass.kt new file mode 100644 index 00000000000..4d7504f26ac --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/implementComparableInSubclass.kt @@ -0,0 +1,22 @@ +// See KT-12865 + +package foo + +abstract class Base { + val x = 23 +} + +class Derived : Base(), Comparable { + val y = 42 + override fun compareTo(other: Derived): Int { + throw UnsupportedOperationException("not implemented") + } +} + +fun box(): String { + val b = Derived() + if (b.x != 23) return "fail1: ${b.x}" + if (b.y != 42) return "fail2: ${b.y}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/classes/inheritSetAndHashSet.kt b/backend.native/tests/external/codegen/blackbox/classes/inheritSetAndHashSet.kt new file mode 100644 index 00000000000..1bdc245676f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/inheritSetAndHashSet.kt @@ -0,0 +1,9 @@ +interface A : Set + +class B : A, HashSet() + +fun box(): String { + val b = B() + b.add("OK") + return b.iterator().next() +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/inheritance.kt b/backend.native/tests/external/codegen/blackbox/classes/inheritance.kt new file mode 100644 index 00000000000..78d6d58fa3b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/inheritance.kt @@ -0,0 +1,41 @@ +// Changed when traits were introduced. May not make sense any more + +open class X(val x : Int) {} +interface Y { + abstract val y : Int +} + +class YImpl(override val y : Int) : Y {} + +class Point(x : Int, yy : Int) : X(x) , Y { + override val y : Int = yy +} + +interface Abstract {} + +class P1(x : Int, yy : Y) : Abstract, X(x), Y by yy {} +class P2(x : Int, yy : Y) : X(x), Abstract, Y by yy {} +class P3(x : Int, yy : Y) : X(x), Y by yy, Abstract {} +class P4(x : Int, yy : Y) : Y by yy, Abstract, X(x) {} + +fun box() : String { + if (X(239).x != 239) return "FAIL #1" + if (YImpl(239).y != 239) return "FAIL #2" + + val p = Point(240, -1) + if (p.x + p.y != 239) return "FAIL #3" + + val y = YImpl(-1) + val p1 = P1(240, y) + if (p1.x + p1.y != 239) return "FAIL #4" + val p2 = P2(240, y) + if (p2.x + p2.y != 239) return "FAIL #5" + + val p3 = P3(240, y) + if (p3.x + p3.y != 239) return "FAIL #6" + + val p4 = P4(240, y) + if (p4.x + p4.y != 239) return "FAIL #7" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/inheritedInnerClass.kt b/backend.native/tests/external/codegen/blackbox/classes/inheritedInnerClass.kt new file mode 100644 index 00000000000..82bd91e93cd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/inheritedInnerClass.kt @@ -0,0 +1,14 @@ +class Outer() { + open inner class InnerBase() { + } + + inner class InnerDerived(): InnerBase() { + } + + public val foo: InnerBase? = InnerDerived() +} + +fun box() : String { + val o = Outer() + return if (o.foo === null) "fail" else "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/inheritedMethod.kt b/backend.native/tests/external/codegen/blackbox/classes/inheritedMethod.kt new file mode 100644 index 00000000000..fb9c3bfe080 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/inheritedMethod.kt @@ -0,0 +1,13 @@ +open class Foo { + fun xyzzy(): String = "xyzzy" +} + +class Bar(): Foo() { + fun test(): String = xyzzy() +} + +fun box() : String { + val bar = Bar() + val f = bar.test() + return if (f == "xyzzy") "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/initializerBlock.kt b/backend.native/tests/external/codegen/blackbox/classes/initializerBlock.kt new file mode 100644 index 00000000000..ccaac7f0473 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/initializerBlock.kt @@ -0,0 +1,13 @@ +class C() { + public var f: Int + + init { + f = 610 + } +} + +fun box(): String { + val c = C() + if (c.f != 610) return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/initializerBlockDImpl.kt b/backend.native/tests/external/codegen/blackbox/classes/initializerBlockDImpl.kt new file mode 100644 index 00000000000..087f4ab0c54 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/initializerBlockDImpl.kt @@ -0,0 +1,18 @@ +// WITH_RUNTIME +class World() { + public val items: ArrayList = ArrayList() + + inner class Item() { + init { + items.add(this) + } + } + + val foo = Item() +} + +fun box() : String { + val w = World() + if (w.items.size != 1) return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/inner/instantiateInDerived.kt b/backend.native/tests/external/codegen/blackbox/classes/inner/instantiateInDerived.kt new file mode 100644 index 00000000000..2f928428baf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/inner/instantiateInDerived.kt @@ -0,0 +1,40 @@ +open class A(val value: String) { + inner class B(val s: String) { + val result = value + "_" + s + } +} + +class C : A("fromC") { + fun classReceiver() = B("OK") + fun superReceiver() = super.B("OK") + + fun newAReceiver() = A("fromA").B("OK") + fun aReceiver(): B { + val a = A("fromA") + return a.B("OK") + } + + fun A.extReceiver() = this.B("OK") + fun extReceiver() = A("fromA").extReceiver() +} + +fun box(): String { + val receiver = C() + var result = receiver.classReceiver().result + if (result != "fromC_OK") return "fail 1: $result" + + result = receiver.superReceiver().result + if (result != "fromC_OK") return "fail 2: $result" + + + result = receiver.aReceiver().result + if (result != "fromA_OK") return "fail 3: $result" + + result = receiver.newAReceiver().result + if (result != "fromA_OK") return "fail 3: $result" + + result = receiver.extReceiver().result + if (result != "fromA_OK") return "fail 3: $result" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/classes/inner/instantiateInDerivedLabeled.kt b/backend.native/tests/external/codegen/blackbox/classes/inner/instantiateInDerivedLabeled.kt new file mode 100644 index 00000000000..34db2545d47 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/inner/instantiateInDerivedLabeled.kt @@ -0,0 +1,42 @@ +open class A(val value: String) { + inner class B(val s: String) { + val result = value + "_" + s + } +} + +class C : A("fromC") { + + inner class X: A("fromX") { + fun classReceiver() = B("OK") + fun superReceiver() = super.B("OK") + fun superXReceiver() = super@X.B("OK") + fun superXCastReceiver() = (this@X as A).B("OK") + + fun superCReceiver() = super@C.B("OK") + fun superCCastReceiver() = (this@C as A).B("OK") + } +} + +fun box(): String { + val receiver = C().X() + var result = receiver.classReceiver().result + if (result != "fromX_OK") return "fail 1: $result" + + result = receiver.superReceiver().result + if (result != "fromX_OK") return "fail 2: $result" + + result = receiver.superXReceiver().result + if (result != "fromX_OK") return "fail 3: $result" + + result = receiver.superXCastReceiver().result + if (result != "fromX_OK") return "fail 4: $result" + + + result = receiver.superCReceiver().result + if (result != "fromC_OK") return "fail 3: $result" + + result = receiver.superCCastReceiver().result + if (result != "fromC_OK") return "fail 4: $result" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/classes/inner/instantiateInSameClass.kt b/backend.native/tests/external/codegen/blackbox/classes/inner/instantiateInSameClass.kt new file mode 100644 index 00000000000..bc6200c60c5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/inner/instantiateInSameClass.kt @@ -0,0 +1,34 @@ +class C(val value: String = "C") { + + inner class B(val s: String) { + val result = value + "_" + s + } + + fun classReceiver() = B("OK") + + fun newCReceiver() = C("newC").B("OK") + fun cReceiver(): B { + val c = C("newC") + return c.B("OK") + } + + fun C.extReceiver1() = this.B("OK") + fun extReceiver() = C("newC").extReceiver1() +} + +fun box(): String { + val receiver = C() + var result = receiver.classReceiver().result + if (result != "C_OK") return "fail 1: $result" + + result = receiver.cReceiver().result + if (result != "newC_OK") return "fail 3: $result" + + result = receiver.newCReceiver().result + if (result != "newC_OK") return "fail 3: $result" + + result = receiver.extReceiver().result + if (result != "newC_OK") return "fail 3: $result" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/classes/inner/kt6708.kt b/backend.native/tests/external/codegen/blackbox/classes/inner/kt6708.kt new file mode 100644 index 00000000000..db242e7c0bb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/inner/kt6708.kt @@ -0,0 +1,12 @@ +open class A() { + open inner class InnerA +} + +class B : A() { + inner class InnerB : A.InnerA() +} + +fun box(): String { + B().InnerB() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/classes/inner/properOuter.kt b/backend.native/tests/external/codegen/blackbox/classes/inner/properOuter.kt new file mode 100644 index 00000000000..41d1e4406db --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/inner/properOuter.kt @@ -0,0 +1,16 @@ + +open class A(val s: String) { + open inner class B(val s: String) { + fun testB() = s + this@A.s + } + + open inner class C(): A("C") { + fun testC() = + B("B_").testB() + } +} + +fun box(): String { + val res = A("A").C().testC() + return if (res == "B_C") "OK" else res; +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/classes/inner/properSuperLinking.kt b/backend.native/tests/external/codegen/blackbox/classes/inner/properSuperLinking.kt new file mode 100644 index 00000000000..230ad1d9ee4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/inner/properSuperLinking.kt @@ -0,0 +1,16 @@ + +open class A(val s: String) { + + val z = s + + fun test() = s + + open inner class B(s: String): A(s) { + fun testB() = z + test() + } +} + +fun box(): String { + val res = A("Fail").B("OK").testB() + return if (res == "OKOK") "OK" else res; +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/classes/innerClass.kt b/backend.native/tests/external/codegen/blackbox/classes/innerClass.kt new file mode 100644 index 00000000000..8f43233aa95 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/innerClass.kt @@ -0,0 +1,19 @@ +class Outer(val foo: StringBuilder) { + inner class Inner() { + fun len() : Int { + return foo.length + } + } + + fun test() : Inner { + return Inner() + } +} + +fun box() : String { + val sb = StringBuilder("xyzzy") + val o = Outer(sb) + val i = o.test() + val l = i.len() + return if (l != 5) "fail" else "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/interfaceCompanionInitializationWithJava.kt b/backend.native/tests/external/codegen/blackbox/classes/interfaceCompanionInitializationWithJava.kt new file mode 100644 index 00000000000..0db5f2d4372 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/interfaceCompanionInitializationWithJava.kt @@ -0,0 +1,36 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FILE: CompanionInitialization.java + +public class CompanionInitialization { + + public static Object getCompanion() { + return IStatic.Companion; + } + +} + +// FILE: CompanionInitialization.kt + +open class Static(): IStatic { + val p = IStatic::class.java.getDeclaredField("const").get(null) +} + +interface IStatic { + fun doSth() { + } + + companion object : Static() { + const val const = 1; + } +} + +fun box(): String { + IStatic.doSth() + + val companion: Any? = CompanionInitialization.getCompanion() + if (companion == null) return "fail 1" + if (companion != IStatic) return "fail 2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1018.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1018.kt new file mode 100644 index 00000000000..6e192f5e0be --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1018.kt @@ -0,0 +1,12 @@ +public class StockMarketTableModel() { + + public fun getColumnCount() : Int { + return COLUMN_TITLES?.size!! + } + + companion object { + private val COLUMN_TITLES : Array = arrayOfNulls(10) + } +} + +fun box() : String = if(StockMarketTableModel().getColumnCount()==10) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1120.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1120.kt new file mode 100644 index 00000000000..69a428951cd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1120.kt @@ -0,0 +1,19 @@ +// Won't ever work with JS backend. +// TODO: Consider rewriting this test without using threads, since the issue is not about threads at all. +// IGNORE_BACKEND: JS, NATIVE + +object RefreshQueue { + val any = Any() + val workerThread: Thread = Thread(object : Runnable { + override fun run() { + val a = any + val b = RefreshQueue.any + if (a != b) throw AssertionError() + } + }) +} + +fun box() : String { + RefreshQueue.workerThread.run() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1134.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1134.kt new file mode 100644 index 00000000000..cbe62018fd4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1134.kt @@ -0,0 +1,9 @@ +// TODO: Enable when JS backend supports Java class library +// IGNORE_BACKEND: JS, NATIVE +public class SomeClass() : java.lang.Object() { +} + +public fun box():String { + System.out?.println(SomeClass().getClass()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1157.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1157.kt new file mode 100644 index 00000000000..126889d5110 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1157.kt @@ -0,0 +1,21 @@ +public object SomeClass { + private val work = object : Runnable { + override fun run() { + foo() + } + } + + private fun foo(): Unit { + } + + public fun run(): Unit = work.run() +} + +interface Runnable { + fun run(): Unit +} + +fun box(): String { + SomeClass.run() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1247.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1247.kt new file mode 100644 index 00000000000..4ba62b57487 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1247.kt @@ -0,0 +1,6 @@ +fun f(a : Int?, b : Int.(Int)->Int) = a?.b(1) + +fun box(): String { + val x = f(1) { this+it+2 } + return if (x == 4) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1345.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1345.kt new file mode 100644 index 00000000000..3933f9c552e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1345.kt @@ -0,0 +1,13 @@ +interface Creator { + fun create() : T +} + +class Actor(val code: String = "OK") + +interface Factory : Creator + +class MyFactory() : Factory { + override fun create(): Actor = Actor() +} + +fun box() : String = MyFactory().create().code diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1439.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1439.kt new file mode 100644 index 00000000000..f5cd98d49c4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1439.kt @@ -0,0 +1,17 @@ +class MyClass(var fnc : () -> String) { + + fun test(): String { + return fnc() + } + +} + +fun printtest() : String { + return "OK" +} + +fun box(): String { + var c = MyClass({ printtest() }) + + return c.test() +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1535.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1535.kt new file mode 100644 index 00000000000..d26691e4446 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1535.kt @@ -0,0 +1,22 @@ +// TODO: Enable when JS backend supports Java class library, since FunctionX are required for interoperation +// IGNORE_BACKEND: JS, NATIVE +class Works() : Function0 { + public override fun invoke():Any { + return "Works" as Any + } +} +class Broken() : Function0 { + public override fun invoke():String { + return "Broken" + } +} + +fun box(): String { + val works1: ()->Any = Works(); + works1() + + val broken1: ()->String = Broken(); + broken1() + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1538.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1538.kt new file mode 100644 index 00000000000..e412b9885e3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1538.kt @@ -0,0 +1,21 @@ +data class Pair(val first: First, val second: Second) + +fun parseCatalogs(hashMap: Any?) { + val r = toHasMap(hashMap) + if (!r.first) { + return + } + val nodes = r.second +} + +fun toHasMap(value: Any?): Pair?> { + if(value is HashMap<*, *>) { + return Pair(true, value as HashMap) + } + return Pair(false, null as HashMap?) +} + +fun box() : String { + parseCatalogs(null) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1578.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1578.kt new file mode 100644 index 00000000000..e485684b4da --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1578.kt @@ -0,0 +1,9 @@ +fun box() : String { + var i = 0 + { + i++ + }() + i++ //the problem is here +// i = i + 1 //this way it works + return if (i == 2) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1611.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1611.kt new file mode 100644 index 00000000000..b04a15ef70e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1611.kt @@ -0,0 +1,11 @@ +fun box(): String { + return Foo().doBar("OK") +} + +class Foo() { + val bar : (str : String) -> String = { it } + + fun doBar(str : String): String { + return bar(str); + } +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1721.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1721.kt new file mode 100644 index 00000000000..c38869f87b8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1721.kt @@ -0,0 +1,6 @@ +class T(val f : () -> Any?) { + fun call() : Any? = f() +} +fun box(): String { + return T({ "OK" }).call() as String +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1726.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1726.kt new file mode 100644 index 00000000000..c718ea84028 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1726.kt @@ -0,0 +1,15 @@ +class Foo( + var state : Int, + val f : (Int) -> Int){ + + fun next() : Int { + val nextState = f(state) + state = nextState + return state + } +} + +fun box(): String { + val f = Foo(23, {x -> 2 * x}) + return if (f.next() == 46) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1759.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1759.kt new file mode 100644 index 00000000000..b34b725c39b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1759.kt @@ -0,0 +1,10 @@ +class Greeter(var name : String) { + fun greet() { + name = name.plus("") + } +} + +fun box() : String { + Greeter("OK").greet() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1891.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1891.kt new file mode 100644 index 00000000000..e9183589db3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1891.kt @@ -0,0 +1,14 @@ +class MyList() { + var value: T? = null + + operator fun get(index: Int): T = value!! + + operator fun set(index: Int, value: T) { this.value = value } +} + +fun box(): String { + val list = MyList() + list[17] = 1 + list[17] = list[18]++ + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1918.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1918.kt new file mode 100644 index 00000000000..1da1471e2d3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1918.kt @@ -0,0 +1,20 @@ +class Bar { +} + +interface Foo { + fun xyzzy(x: Any?): String +} + +fun buildFoo(bar: Bar.() -> Unit): Foo { + return object : Foo { + override fun xyzzy(x: Any?): String { + (x as? Bar)?.bar() + return "OK" + } + } +} + +fun box(): String { + val foo = buildFoo({}) + return foo.xyzzy(Bar()) +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1976.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1976.kt new file mode 100644 index 00000000000..7e02add4ef3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1976.kt @@ -0,0 +1,8 @@ +class A { + public val f : ()->String = {"OK"} +} + +fun box(): String { + val a = A() + return a.f() // does not work: (in runtime) ClassCastException: A cannot be cast to kotlin.Function0 +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt1980.kt b/backend.native/tests/external/codegen/blackbox/classes/kt1980.kt new file mode 100644 index 00000000000..74414304f25 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt1980.kt @@ -0,0 +1,27 @@ +public inline fun Int.times(body : () -> Unit) { + var count = this; + while (count > 0) { + body() + count-- + } +} + +fun calc() : Int { + val a = ArrayList<()->Int>() + 2.times { + var j = 1 + a.add({ j }) + ++j + } + var sum = 0 + for (f in a) { + val g = f as () -> Int + sum += g() + } + return sum +} + +fun box() : String { + val x = calc() + return if (x == 4) "OK" else x.toString() +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2224.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2224.kt new file mode 100644 index 00000000000..fe6d9bcbe48 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2224.kt @@ -0,0 +1,44 @@ +interface A { + fun foo(): Int +} + +class B1 : A { + override fun foo() = 10 +} + +class B2(val z: Int) : A { + override fun foo() = z +} + + + +fun f1(b: B1): Int { + val o = object : A by b { } + return o.foo() +} + +fun f2(b: B2): Int { + val o = object : A by B2(b.z) { } + return o.foo() +} + +fun f3(b: B2, mult: Int): Int { + val o = object : A by B2(mult * b.z) { } + return o.foo() +} + +fun f4(b: B1, x: Int, y: Int, z: Int): Int { + val o = object : A by b { + fun bar() = x + y + z + } + return o.foo() +} + + +fun box(): String { + if (f1(B1()) != 10) return "fail #1" + if (f2(B2(239)) != 239) return "fail #2" + if (f3(B2(239), 2) != 239*2) return "fail #3" + if (f4(B1(), 1, 2, 3) != 10) return "fail #4" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2288.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2288.kt new file mode 100644 index 00000000000..773d737f06a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2288.kt @@ -0,0 +1,10 @@ +// TODO: Enable when JS backend supports Java class library +// IGNORE_BACKEND: JS, NATIVE +public open class Test(): java.util.RandomAccess, Cloneable, java.io.Serializable +{ + public override fun clone(): Test = Test() // Override 'clone()' with more precise type 'Test' + + public override fun toString() = "OK" +} + +fun box() = Test().clone().toString() diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2384.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2384.kt new file mode 100644 index 00000000000..d990d4cbc00 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2384.kt @@ -0,0 +1,15 @@ +class A { + companion object { + val b = 0 + val c = b + + init { + val d = b + } + } +} + +fun box(): String { + A() + return if (A.c == A.b) "OK" else "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2390.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2390.kt new file mode 100644 index 00000000000..9d664ee825d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2390.kt @@ -0,0 +1,35 @@ + +class JsonObject() { +} + +class JsonArray() { +} + +public interface Formatter { + public fun format(source: IN?): OUT +} + +public interface MultiFormatter { + public fun format(source: Collection): OUT +} + +public class Project() { +} + +public interface JsonFormatter: Formatter, MultiFormatter { + public override fun format(source: Collection): JsonArray { + return JsonArray(); + } +} + +public class ProjectJsonFormatter(): JsonFormatter { + public override fun format(source: Project?): JsonObject { + return JsonObject() + } +} + + +fun box(): String { + val formatter = ProjectJsonFormatter() + return if (formatter.format(Project()) != null) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2391.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2391.kt new file mode 100644 index 00000000000..2176c01b98e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2391.kt @@ -0,0 +1,19 @@ +public interface LoggerAware { + public val logger: StringBuilder +} + +public abstract class HttpServer(): LoggerAware { + public fun start() { + logger.append("OK") + } +} + +public class MyHttpServer(): HttpServer() { + public override val logger = StringBuilder() +} + +fun box(): String { + val server = MyHttpServer() + server.start() + return server.logger.toString()!! +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2395.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2395.kt new file mode 100644 index 00000000000..ccd1b1c5356 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2395.kt @@ -0,0 +1,13 @@ +// TARGET_BACKEND: JVM + +import java.util.AbstractList + +class MyList(): AbstractList() { + public fun getModificationCount(): Int = modCount + public override fun get(index: Int): String = "" + public override val size: Int get() = 0 +} + +fun box(): String { + return if (MyList().getModificationCount() == 0) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2417.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2417.kt new file mode 100644 index 00000000000..fe584cce56a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2417.kt @@ -0,0 +1,23 @@ +fun box() : String{ + val set = HashSet() + set.add("foo") + val t1 = "foo" in set // returns true, valid + if(!t1) return "fail1" + val t2 = "foo" !in set // returns true, invalid + if(t2) return "fail2" + val t3 = "bar" in set // returns false, valid + if(t3) return "fail3" + val t4 = "bar" !in set // return false, invalid + if(!t4) return "fail4" + val t5 = when("foo") { + in set -> true + else -> false + } + if(!t5) return "fail5" + val t6 = when("foo") { + !in set -> true + else -> false + } + if(t6) return "fail6" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2477.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2477.kt new file mode 100644 index 00000000000..8f45431717c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2477.kt @@ -0,0 +1,23 @@ +package test + +interface A { + public val c: String + get() = "OK" +} + +interface B { + private val c: String + get() = "FAIL" +} + +open class C { + private val c: String = "FAIL" +} + +open class D: C(), A, B { + val b = c +} + +fun box() : String { + return D().c +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2480.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2480.kt new file mode 100644 index 00000000000..cbeec9ce597 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2480.kt @@ -0,0 +1,13 @@ +fun box() = Class().printSome() + +public abstract class AbstractClass { + public fun printSome() : T = some + + public abstract val some: T +} + +public class Class: AbstractClass() { + public override val some: String + get() = "OK" + +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2482.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2482.kt new file mode 100644 index 00000000000..6a614198741 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2482.kt @@ -0,0 +1,9 @@ +public fun box() : String { + if ( 0 == 0 ) { // Does not crash if either this... + if ( 0 == 0 ) { // ...or this is changed to if ( true ) + // Does not crash if the following is uncommented. + //println("foo") + } + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2485.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2485.kt new file mode 100644 index 00000000000..5ef24c24577 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2485.kt @@ -0,0 +1,12 @@ +fun f1(a : Any?) {} +fun f2(a : Boolean?) {} +fun f3(a : Any) {} +fun f4(a : Boolean) {} + +fun box() : String { + f1(1 == 1) + f2(1 == 1) + f3(1 == 1) + f4(1 == 1) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt249.kt b/backend.native/tests/external/codegen/blackbox/classes/kt249.kt new file mode 100644 index 00000000000..afd8fa0a0a7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt249.kt @@ -0,0 +1,13 @@ +package x + +class Outer() { + companion object { + class Inner() { + } + } +} + +fun box (): String { + val inner = Outer.Companion.Inner() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2532.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2532.kt new file mode 100644 index 00000000000..24d12e9f884 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2532.kt @@ -0,0 +1,15 @@ +package foo + +interface B { + val c: Int + get() = 2 +} + +class A(val b: B) : B by b { + override val c: Int = 3 +} + +fun box(): String { + val c = A(object: B {}).c + return if (c == 3) "OK" else "fail: $c" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2566.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2566.kt new file mode 100644 index 00000000000..6a134feb84f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2566.kt @@ -0,0 +1,15 @@ +open class A { + open fun foo() = "OK" +} + +open class B : A() { + override fun foo() = super.foo() +} + +interface I + +class C : I, B() { + override fun foo() = super.foo() +} + +fun box() = C().foo() diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2566_2.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2566_2.kt new file mode 100644 index 00000000000..b119af85615 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2566_2.kt @@ -0,0 +1,17 @@ +open class A { + open val foo: String = "OK" +} + +open class B : A() { + inner class E { + val foo: String = super@B.foo + } +} + +class C : B() { + inner class D { + val foo: String = super@C.foo + } +} + +fun box() = C().foo diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2607.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2607.kt new file mode 100644 index 00000000000..10688476918 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2607.kt @@ -0,0 +1,9 @@ +fun box() : String { + val o = object { + + inner class C { + fun foo() = "OK" + } + } + return o.C().foo() +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2626.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2626.kt new file mode 100644 index 00000000000..34ba1d2ad8d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2626.kt @@ -0,0 +1,10 @@ +package example2 + +fun box() = Context.OsType.OK.toString() + +object Context +{ + public enum class OsType { + WIN2000, WINDOWS, MACOSX, LINUX, OTHER, OK; + } +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2711.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2711.kt new file mode 100644 index 00000000000..409537ae567 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2711.kt @@ -0,0 +1,15 @@ +class IntRange { + operator fun contains(a: Int) = (1..2).contains(a) +} + +class C() { + operator fun rangeTo(i: Int) = IntRange() +} + + +fun box(): String { + if (2 in C()..2) { + 2 == 2 + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt2784.kt b/backend.native/tests/external/codegen/blackbox/classes/kt2784.kt new file mode 100644 index 00000000000..fc7c5dfccbe --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt2784.kt @@ -0,0 +1,10 @@ +open class Factory(p: Int) + +class A { + companion object : Factory(1) +} + +fun box() : String { + A + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt285.kt b/backend.native/tests/external/codegen/blackbox/classes/kt285.kt new file mode 100644 index 00000000000..945b250f7dc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt285.kt @@ -0,0 +1,15 @@ +interface Trait { + fun foo() = "O" + fun bar(): String +} + +class SimpleClass : Trait { + override fun bar() = "K" +} + +// Delegating 'toString' doesn't work, see KT-9519 +class ComplexClass : Trait by SimpleClass() { + fun qux() = foo() + bar() +} + +fun box() = ComplexClass().qux() diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt3001.kt b/backend.native/tests/external/codegen/blackbox/classes/kt3001.kt new file mode 100644 index 00000000000..0524528ca1e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt3001.kt @@ -0,0 +1,11 @@ +interface A { + val result: String +} + +class Base(override val result: String) : A + +open class Derived : A by Base("OK") + +class Z : Derived() + +fun box() = Z().result diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt3114.kt b/backend.native/tests/external/codegen/blackbox/classes/kt3114.kt new file mode 100644 index 00000000000..32d42899074 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt3114.kt @@ -0,0 +1,13 @@ +class KeySpan(val left: String) { + + public fun matches(value : String) : Boolean { + + return left > value && left > value + } + +} + +fun box() : String { + KeySpan("1").matches("3") + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt3414.kt b/backend.native/tests/external/codegen/blackbox/classes/kt3414.kt new file mode 100644 index 00000000000..6b4a083eda9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt3414.kt @@ -0,0 +1,18 @@ +interface A { + fun foo(): Int +} + +interface B { + fun foo(): Int +} + +class Z(val a: A) : A by a, B + +fun box(): String { + val s = Z(object : A { + override fun foo(): Int { + return 1; + } + }); + return if (s.foo() == 1) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt343.kt b/backend.native/tests/external/codegen/blackbox/classes/kt343.kt new file mode 100644 index 00000000000..adae992ae21 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt343.kt @@ -0,0 +1,22 @@ +fun launch(f : () -> Unit) { + f() +} + +fun box(): String { + val list = ArrayList() + val foo : () -> Unit = { + list.add(2) //first exception + } + foo() + + launch({ + list.add(3) + }) + + val bar = { + val x = 1 //second exception + } + bar() + + return if (list.size == 2 && list.get(0) == 2 && list.get(1) == 3) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt3546.kt b/backend.native/tests/external/codegen/blackbox/classes/kt3546.kt new file mode 100644 index 00000000000..b4d36c1f3e6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt3546.kt @@ -0,0 +1,25 @@ +interface A { + fun test(): String +} + +interface B { + fun test(): String +} + +interface C: A, B + +class Z(val param: String): C { + + override fun test(): String { + return param + } +} + +public class MyClass(val value : C) : C by value { + +} + +fun box(): String { + val s = MyClass(Z("OK")) + return s.test() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt454.kt b/backend.native/tests/external/codegen/blackbox/classes/kt454.kt new file mode 100644 index 00000000000..be3994d660c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt454.kt @@ -0,0 +1,5 @@ +fun box(): String { + var s1 = (l1@ "s") + val s2 = (l2@ if (l3@ true) s1 else null) + return if (s2 == "s") "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt471.kt b/backend.native/tests/external/codegen/blackbox/classes/kt471.kt new file mode 100644 index 00000000000..4de658a6626 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt471.kt @@ -0,0 +1,109 @@ +class MyNumber(val i: Int) { + operator fun inc(): MyNumber = MyNumber(i+1) +} + +class MNR(var ref: MyNumber) {} + +fun test1() : Boolean { + var m = MyNumber(42) + + m++ + if (m.i != 43) return false + return true +} + +fun test2() : Boolean { + var m = MyNumber(44) + + var m2 = m++ + if (m2.i != 44) return false + if (m.i != 45) return false + return true +} + +fun test3() : Boolean { + var mnr = MNR(MyNumber(42)) + mnr.ref++ + if (mnr.ref.i != 43) return false + return true +} + +fun test4() : Boolean { + var mnr = MNR(MyNumber(42)) + val m3 = mnr.ref++ + if (m3.i != 42) return false + return true +} + +fun test5() : Boolean { + var mnr = Array(2,{MyNumber(42)}) + mnr[0]++ + if (mnr[0].i != 43) return false + return true +} + +fun test6() : Boolean { + var mnr = Array(2,{it -> MyNumber(42-it)}) + mnr[1] = mnr[0]++ + if (mnr[0].i != 43) return false + if (mnr[1].i != 42) return false + return true +} + +class MyArrayList() { + private var value17: T? = null + private var value39: T? = null + operator fun get(index: Int): T { + if (index == 17) return value17!! + if (index == 39) return value39!! + throw Exception() + } + operator fun set(index: Int, value: T): T? { + if (index == 17) value17 = value + else if (index == 39) value39 = value + else throw Exception() + return null + } +} + +fun test7() : Boolean { + var mnr = MyArrayList() + mnr[17] = MyNumber(42) + mnr[17]++ + if (mnr[17].i != 43) return false + return true +} + +fun test8() : Boolean { + var mnr = MyArrayList() + mnr[17] = MyNumber(42) + mnr[39] = mnr[17]++ + if (mnr[17].i != 43) return false + if (mnr[39].i != 42) return false + return true +} + + +fun box() : String { + var m = MyNumber(42) + + if (!test1()) return "fail test 1" + if (!test2()) return "fail test 2" + if (!test3()) return "fail test 3" + if (!test4()) return "fail test 4" + + if (!test5()) return "fail test 5" + if (!test6()) return "fail test 6" + if (!test7()) return "fail test 7" + if (!test8()) return "fail test 8" + + + ++m + if (m.i != 43) return "fail 0" + + var m1 = ++m + if (m1.i != 44) return "fail 3" + if (m.i != 44) return "fail 4" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt48.kt b/backend.native/tests/external/codegen/blackbox/classes/kt48.kt new file mode 100644 index 00000000000..007c5958af0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt48.kt @@ -0,0 +1,29 @@ +class A() { + var xi = 0 + var xin : Int? = 0 + var xinn : Int? = null + + var xl = 0.toLong() + var xln : Long? = 0.toLong() + var xlnn : Long? = null + + var xb = 0.toByte() + var xbn : Byte? = 0.toByte() + var xbnn : Byte? = null + + var xf = 0.toFloat() + var xfn : Float? = 0.toFloat() + var xfnn : Float? = null + + var xd = 0.toDouble() + var xdn : Double? = 0.toDouble() + var xdnn : Double? = null + + var xs = 0.toShort() + var xsn : Short? = 0.toShort() + var xsnn : Short? = null +} + +fun box() : String { + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt496.kt b/backend.native/tests/external/codegen/blackbox/classes/kt496.kt new file mode 100644 index 00000000000..e4c31c86a27 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt496.kt @@ -0,0 +1,83 @@ +fun test1() : Boolean { + try { + return true + } finally { + if(true) // otherwise we wisely have unreachable code + return false + } +} + +var x = true +fun test2() : Boolean { + try { + } finally { + x = false; + } + return x +} + +fun test3() : Int { + var y = 0 + try { + ++y + } finally { + ++y + } + return y +} + +var z = 0 +fun test4() : Int { + z = 0 + return try { + try { + z++ + } + finally { + z++ + } + } finally { + ++z + } +} + +fun test5() : Int { + var x = 0 + while(true) { + try { + if(x < 10) + x++ + else + break + } + finally { + x++ + } + } + return x +} + +fun test6() : Int { + var x = 0 + while(x < 10) { + try { + x++ + continue + } + finally { + x++ + } + } + return x +} + +fun box() : String { + if(test1()) return "test1 failed" + if(test2()) return "test2 failed" + if(test3() != 2) return "test3 failed" + if(test4() != 0) return "test4 failed" + if(test5() != 11) return "test5 failed" + if(test6() != 10) return "test6 failed" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt500.kt b/backend.native/tests/external/codegen/blackbox/classes/kt500.kt new file mode 100644 index 00000000000..b9c66165f9e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt500.kt @@ -0,0 +1,29 @@ +var GUEST_USER_ID = 3 +val USER_ID = + try { + getUserIdFromEnvironment() + } + catch (e : UnsupportedOperationException) { + ++GUEST_USER_ID + } + +val USER_ID_2 = + try { + getUserIdFromEnvironment() + } + catch (e : UnsupportedOperationException) { + GUEST_USER_ID + } + finally { + GUEST_USER_ID++ + } + +fun getUserIdFromEnvironment() : Int = throw UnsupportedOperationException() + +fun box() : String { + if(USER_ID != 4) return "test0 failed" + if(USER_ID_2 != 4) return "test2 failed" + if(GUEST_USER_ID != 5) return "test3 failed" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt501.kt b/backend.native/tests/external/codegen/blackbox/classes/kt501.kt new file mode 100644 index 00000000000..6705704587e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt501.kt @@ -0,0 +1,22 @@ +class Reluctant() { + init { + throw Exception("I'm not coming out") + } +} + +fun test1() : String { + try { + val b = Reluctant() + return "Surprise!" + } + catch (ex : Exception) { + return "I told you so" + } +} + + +fun box() : String { + if(test1() != "I told you so") return "test1 failed" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt504.kt b/backend.native/tests/external/codegen/blackbox/classes/kt504.kt new file mode 100644 index 00000000000..2f55f67acdd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt504.kt @@ -0,0 +1,17 @@ +package mult_constructors_3_bug + +public open class Identifier() { + private var myNullable : Boolean = true + companion object { + open public fun init(isNullable : Boolean) : Identifier { + val id = Identifier() + id.myNullable = isNullable + return id + } + } +} + +fun box() : String { + Identifier.init(true) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt508.kt b/backend.native/tests/external/codegen/blackbox/classes/kt508.kt new file mode 100644 index 00000000000..29d4283a7be --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt508.kt @@ -0,0 +1,16 @@ +// TODO: Enable for JS when it supports Java class library. +// IGNORE_BACKEND: JS, NATIVE +// fails on JS with TypeError: imported$plus is not a function, it is undefined. + +operator fun MutableMap.set(key : K, value : V) = put(key, value) + +fun box() : String { + + val commands : MutableMap = HashMap() + + commands["c1"] = "239" + if(commands["c1"] != "239") return "fail" + + commands["c1"] += "932" + return if(commands["c1"] == "239932") "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt5347.kt b/backend.native/tests/external/codegen/blackbox/classes/kt5347.kt new file mode 100644 index 00000000000..cca6a97b08e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt5347.kt @@ -0,0 +1,44 @@ +fun test1(str: String): String { + data class A(val x: Int) { + fun foo() = str + } + return A(0).copy().foo() +} + +class TestClass(val x: String) { + fun foo(): String { + data class A(val x: Int) { + fun foo() = this@TestClass.x + } + return A(0).copy().foo() + } +} + +fun test2(str: String): String = TestClass(str).foo() + +fun test3(str: String): String { + var xx = "" + data class A(val x: Int) { + fun foo(): String { xx = str; return xx } + } + return A(0).copy().foo() +} + +fun test4(str: String): String { + var xx = "" + fun bar(s: String): String { xx = s; return xx } + data class A(val x: Int) { + fun foo(): String = bar(str) + } + return A(0).copy().foo() +} + +fun box(): String { + return when { + test1("test1") != "test1" -> "Failed #1 (parameter capture)" + test2("test2") != "test2" -> "Failed #2 ('this' capture)" + test3("test3") != "test3" -> "Failed #3 ('var' capture)" + test4("test4") != "test4" -> "Failed #4 (local function capture)" + else -> "OK" + } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt6136.kt b/backend.native/tests/external/codegen/blackbox/classes/kt6136.kt new file mode 100644 index 00000000000..14a14e1c4e0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt6136.kt @@ -0,0 +1,26 @@ +interface Id { + val id: T +} + +data class Actor ( + override val id: Int, + val firstName: String, + val lastName: String +) : Id + +fun box(): String { + val a1 = Actor(1, "Jeff", "Bridges") + + val a1c = a1.copy() + if (a1c.id != a1.id) return "Failed: a1.copy().id==${a1c.id}" + + val a2 = Actor(2, "Jeff", "Bridges") + if (a2 == a1) return "Failed: a2==a1" + + // Assume that our hashCode is good enough for this test :) + if (a2.hashCode() == a1.hashCode()) return "Failed: a2.hashCode()==a1.hashCode()" + + a1.toString() + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt633.kt b/backend.native/tests/external/codegen/blackbox/classes/kt633.kt new file mode 100644 index 00000000000..04e0a26ec12 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt633.kt @@ -0,0 +1,23 @@ +class mInt(val i : Int) { + override fun toString() : String = "mint: $i" + operator fun plus(i : Int) = mInt(this.i + i) + operator fun inc() = mInt(i + 1) +} + +class MyArray() { + val a = Array(10, {mInt(0)}) + operator fun get(i : mInt) : mInt = a[i.i] + operator fun set(i : mInt, v : mInt) { + a[i.i] = v + } +} + +fun box() : String { + val a = MyArray() + var i = mInt(0) + a[i++] + a[i++] = mInt(1) + for (i in 0..9) + a[mInt(i)] + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt6816.kt b/backend.native/tests/external/codegen/blackbox/classes/kt6816.kt new file mode 100644 index 00000000000..ed081c608fb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt6816.kt @@ -0,0 +1,25 @@ +public class CalculatorConstants( + val id: Long = 0, + val detour: Double = 0.0, + val taxi: Double = 0.0, + val loop: Double = 0.0, + val planeCondition: Double = 0.0, + val co2PerKerosene: Double = 0.0, + val freight: Double = 0.0, + val rfi: Double = 0.0, + val rfiAltitude: Double = 0.0, + val averageContribution: Double = 0.0, + val singleContribution: Double = 0.0, + val returnContribution: Double = 0.0, + val defraFactor: Double = 0.0, + val airCondMult: Double = 0.0, + val autoTransMult: Double = 0.0, + val hybridDefault: String? = null, + val travelClassOne: Double = 0.0, + val status: String = "OK" +) + +fun box(): String { + val c = CalculatorConstants() + return c.status +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt707.kt b/backend.native/tests/external/codegen/blackbox/classes/kt707.kt new file mode 100644 index 00000000000..a1cb2833e5d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt707.kt @@ -0,0 +1,11 @@ +// TODO: Enable for JS when it supports Java class library. +// IGNORE_BACKEND: JS, NATIVE +class List(val head: T, val tail: List? = null) + +fun List.mapHead(f: (T)-> T): List = List(f(head), null) + +fun box() : String { + val a: Int = List(1).mapHead{it * 2}.head + System.out?.println(a) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt723.kt b/backend.native/tests/external/codegen/blackbox/classes/kt723.kt new file mode 100644 index 00000000000..6d020a0bc99 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt723.kt @@ -0,0 +1,8 @@ +operator fun Int?.inc() : Int { if (this != null) return this.inc() else throw NullPointerException() } + +public fun box() : String { + var i : Int? = 10 + val j = i++ + + return if(j==10 && 11 == i) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt725.kt b/backend.native/tests/external/codegen/blackbox/classes/kt725.kt new file mode 100644 index 00000000000..3aea020f890 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt725.kt @@ -0,0 +1,8 @@ +operator fun Int?.inc() = this!!.inc() + +public fun box() : String { + var i : Int? = 10 + val j = i++ + + return if(j==10 && 11 == i) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt8011.kt b/backend.native/tests/external/codegen/blackbox/classes/kt8011.kt new file mode 100644 index 00000000000..e4ab453aa33 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt8011.kt @@ -0,0 +1,19 @@ +// WITH_RUNTIME + +fun testFun1(str: String): String { + val local = str + + class Local { + fun foo() = str + } + + val list = listOf(0).map { Local() } + return list[0].foo() +} + +fun box(): String { + return when { + testFun1("test1") != "test1" -> "Fail #1" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt8011a.kt b/backend.native/tests/external/codegen/blackbox/classes/kt8011a.kt new file mode 100644 index 00000000000..9a8fa24c6d9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt8011a.kt @@ -0,0 +1,52 @@ +fun testFun1(str: String): String { + val capture = str + + class A { + val x = capture + } + + return A().x +} + + +fun testFun2(str: String): String { + class A { + val x = str + } + fun bar() = A() + return bar().x +} + + +class TestClass(val str: String) { + var xx: String? = null + + init { + class A { + val x = str + } + + xx = A().x + } +} + +fun testFun3(str: String): String = TestClass(str).xx!! + + +fun String.testFun4(): String { + class A { + val x = this@testFun4 + } + return A().x +} + + +fun box(): String { + return when { + testFun1("test1") != "test1" -> "Fail #1 (local class with capture)" + testFun2("test2") != "test2" -> "Fail #2 (local class with capture ctor in another context)" + testFun3("test3") != "test3" -> "Fail #3 (local class with capture ctor in init{ ... })" + "test4".testFun4() != "test4" -> "Fail #4 (local class with extension receiver)" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt903.kt b/backend.native/tests/external/codegen/blackbox/classes/kt903.kt new file mode 100644 index 00000000000..5c3e51cbe41 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt903.kt @@ -0,0 +1,23 @@ +operator fun Int.plus(a: Int?) = this + a!! + +public open class PerfectNumberFinder() { + open public fun isPerfect(number : Int) : Boolean { + var factors : MutableList = ArrayList() + factors?.add(1) + factors?.add(number) + for (i in 2..(Math.sqrt((number).toDouble()) - 1).toInt()) + if (((number % i) == 0)) { + factors?.add(i) + if (((number / i) != i)) + factors?.add((number / i)) + + } + + var sum : Int = 0 + for (i : Int? in factors) + sum += i + return ((sum - number) == number) + } +} + +fun box () = if (PerfectNumberFinder().isPerfect(28)) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt940.kt b/backend.native/tests/external/codegen/blackbox/classes/kt940.kt new file mode 100644 index 00000000000..f9e99b3716a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt940.kt @@ -0,0 +1,17 @@ +// WITH_RUNTIME + +fun box() : String { + val w = object : Comparator { + + override fun compare(o1 : String?, o2 : String?) : Int { + val l1 : Int = o1?.length ?: 0 + val l2 = o2?.length ?: 0 + return l1 - l2 + } + + override fun equals(obj: Any?): Boolean = obj === this + } + + w.compare("aaa", "bbb") + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/kt9642.kt b/backend.native/tests/external/codegen/blackbox/classes/kt9642.kt new file mode 100644 index 00000000000..414954aab60 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/kt9642.kt @@ -0,0 +1,17 @@ +class Outer { + class Nested { + fun fn(): String { + s = "OK" + return s + } + } + + companion object { + public var s = "fail" + private set + } +} + +fun box(): String { + return Outer.Nested().fn() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/classes/namedClassObject.kt b/backend.native/tests/external/codegen/blackbox/classes/namedClassObject.kt new file mode 100644 index 00000000000..2ff7587752d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/namedClassObject.kt @@ -0,0 +1,12 @@ +class C() { + companion object Foo { + fun create() = 3 + } +} + +fun box(): String { + val c1 = C.Foo.create() + val c2 = C.create() + return if (c1 == 3 && c2 == 3) "OK" else "fail" +} + diff --git a/backend.native/tests/external/codegen/blackbox/classes/outerThis.kt b/backend.native/tests/external/codegen/blackbox/classes/outerThis.kt new file mode 100644 index 00000000000..346e44ecbbf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/outerThis.kt @@ -0,0 +1,12 @@ +class Outer() { + inner class Inner() { + val outer: Outer get() = this@Outer + } + + public val x : Inner = Inner() +} + +fun box() : String { + val o = Outer() + return if (o === o.x.outer) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/overloadBinaryOperator.kt b/backend.native/tests/external/codegen/blackbox/classes/overloadBinaryOperator.kt new file mode 100644 index 00000000000..2333984acfa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/overloadBinaryOperator.kt @@ -0,0 +1,23 @@ +class ArrayWrapper() { + val contents = ArrayList() + + fun add(item: T) { + contents.add(item) + } + + operator fun plus(b: ArrayWrapper): ArrayWrapper { + val result = ArrayWrapper() + result.contents.addAll(contents) + result.contents.addAll(b.contents) + return result + } +} + +fun box(): String { + val v1 = ArrayWrapper() + val v2 = ArrayWrapper() + v1.add("foo") + v2.add("bar") + val v3 = v1 + v2 + return if (v3.contents.size == 2) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/overloadPlusAssign.kt b/backend.native/tests/external/codegen/blackbox/classes/overloadPlusAssign.kt new file mode 100644 index 00000000000..04fa8c842ca --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/overloadPlusAssign.kt @@ -0,0 +1,24 @@ +class ArrayWrapper() { + val contents = ArrayList() + + fun add(item: T) { + contents.add(item) + } + + operator fun plusAssign(rhs: ArrayWrapper) { + contents.addAll(rhs.contents) + } + + operator fun get(index: Int): T { + return contents.get(index)!! + } +} + +fun box(): String { + var v1 = ArrayWrapper() + val v2 = ArrayWrapper() + v1.add("foo") + v2.add("bar") + v1 += v2 + return if (v1.contents.size == 2) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/overloadPlusAssignReturn.kt b/backend.native/tests/external/codegen/blackbox/classes/overloadPlusAssignReturn.kt new file mode 100644 index 00000000000..005c69ce4f9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/overloadPlusAssignReturn.kt @@ -0,0 +1,28 @@ +class ArrayWrapper() { + val contents = ArrayList() + + fun add(item: T) { + contents.add(item) + } + + operator fun plus(rhs: ArrayWrapper): ArrayWrapper { + val result = ArrayWrapper() + result.contents.addAll(contents) + result.contents.addAll(rhs.contents) + return result + } + + operator fun get(index: Int): T { + return contents.get(index)!! + } +} + +fun box(): String { + var v1 = ArrayWrapper() + val v2 = ArrayWrapper() + v1.add("foo") + val v3 = v1 + v2.add("bar") + v1 += v2 + return if (v1.contents.size == 2 && v3.contents.size == 1) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/overloadPlusToPlusAssign.kt b/backend.native/tests/external/codegen/blackbox/classes/overloadPlusToPlusAssign.kt new file mode 100644 index 00000000000..005c69ce4f9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/overloadPlusToPlusAssign.kt @@ -0,0 +1,28 @@ +class ArrayWrapper() { + val contents = ArrayList() + + fun add(item: T) { + contents.add(item) + } + + operator fun plus(rhs: ArrayWrapper): ArrayWrapper { + val result = ArrayWrapper() + result.contents.addAll(contents) + result.contents.addAll(rhs.contents) + return result + } + + operator fun get(index: Int): T { + return contents.get(index)!! + } +} + +fun box(): String { + var v1 = ArrayWrapper() + val v2 = ArrayWrapper() + v1.add("foo") + val v3 = v1 + v2.add("bar") + v1 += v2 + return if (v1.contents.size == 2 && v3.contents.size == 1) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/overloadUnaryOperator.kt b/backend.native/tests/external/codegen/blackbox/classes/overloadUnaryOperator.kt new file mode 100644 index 00000000000..5813e80f4c2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/overloadUnaryOperator.kt @@ -0,0 +1,27 @@ +// WITH_RUNTIME +class ArrayWrapper() { + val contents = ArrayList() + + fun add(item: T) { + contents.add(item) + } + + operator fun unaryMinus(): ArrayWrapper { + val result = ArrayWrapper() + result.contents.addAll(contents) + result.contents.reverse() + return result + } + + operator fun get(index: Int): T { + return contents.get(index)!! + } +} + +fun box(): String { + val v1 = ArrayWrapper() + v1.add("foo") + v1.add("bar") + val v2 = -v1 + return if (v2[0] == "bar" && v2[1] == "foo") "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/privateOuterFunctions.kt b/backend.native/tests/external/codegen/blackbox/classes/privateOuterFunctions.kt new file mode 100644 index 00000000000..ceeb4ff69ce --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/privateOuterFunctions.kt @@ -0,0 +1,35 @@ +class C { + private fun String.ext() : String = "" + private fun f() {} + + public fun foo() : String { + { + "".ext() + f() + }.invoke() + + object : Runnable { + public override fun run() { + "".ext() + f() + } + }.run() + + Inner().innerFun() + + return "OK" + } + + private inner class Inner() { + fun innerFun() { + "".ext() + f() + } + } +} + +interface Runnable { + fun run(): Unit +} + +fun box() = C().foo() diff --git a/backend.native/tests/external/codegen/blackbox/classes/privateOuterProperty.kt b/backend.native/tests/external/codegen/blackbox/classes/privateOuterProperty.kt new file mode 100644 index 00000000000..0f0bc3e452f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/privateOuterProperty.kt @@ -0,0 +1,31 @@ +class C{ + private var v : Int = 0 + + public fun foo() : Int { + { + v = v + 1 + }.invoke() + + object : Runnable { + public override fun run() { + v = v + 1 + } + }.run() + + Inner().innerFun() + + return v + } + + private inner class Inner() { + fun innerFun() { + v = v + 1 + } + } +} + +interface Runnable { + fun run(): Unit +} + +fun box() = if (C().foo() == 3) "OK" else "NOT OK" diff --git a/backend.native/tests/external/codegen/blackbox/classes/privateToThis.kt b/backend.native/tests/external/codegen/blackbox/classes/privateToThis.kt new file mode 100644 index 00000000000..8905986a1f4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/privateToThis.kt @@ -0,0 +1,11 @@ +class A(init_o: I, private val init_k: I) { + private val o: I = init_o + private fun k(): I = init_k + + fun getOk() = o.toString() + k().toString() +} + +fun box(): String { + val a = A("O", "K") + return a.getOk() +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/propertyDelegation.kt b/backend.native/tests/external/codegen/blackbox/classes/propertyDelegation.kt new file mode 100644 index 00000000000..59720282936 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/propertyDelegation.kt @@ -0,0 +1,33 @@ +open class Base() { + val plain = 239 + public val read : Int + get() = 239 + + public var readwrite : Int = 0 + get() = field + 1 + set(n : Int) { + field = n + } +} + +interface Abstract {} + +class Derived1() : Base(), Abstract {} +class Derived2() : Abstract, Base() {} + +fun code(s : Base) : Int { + if (s.plain != 239) return 1 + if (s.read != 239) return 2 + s.readwrite = 238 + if (s.readwrite != 239) return 3 + return 0 +} + +fun test(s : Base) : Boolean = code(s) == 0 + +fun box() : String { + if (!test(Base())) return "Fail #1" + if (!test(Derived1())) return "Fail #2" + if (!test(Derived2())) return "Fail #3" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/propertyInInitializer.kt b/backend.native/tests/external/codegen/blackbox/classes/propertyInInitializer.kt new file mode 100644 index 00000000000..bd8aa833063 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/propertyInInitializer.kt @@ -0,0 +1,16 @@ +class Outer() { + val s = "xyzzy" + + open inner class InnerBase(public val name: String) { + } + + inner class InnerDerived(): InnerBase(s) { + } + + val x = InnerDerived() +} + +fun box() : String { + val o = Outer() + return if (o.x.name != "xyzzy") "fail" else "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/rightHandOverride.kt b/backend.native/tests/external/codegen/blackbox/classes/rightHandOverride.kt new file mode 100644 index 00000000000..2c5af2c9927 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/rightHandOverride.kt @@ -0,0 +1,20 @@ +// Changed when traits were introduced. May not make sense any more + +interface Left {} +open class Right() { + open fun f() = 42 +} + +class D() : Left, Right() { + override fun f() = 239 +} + +fun box() : String { + val r : Right = Right() + val d : D = D() + + if (r.f() != 42) return "Fail #1" + if (d.f() != 239) return "Fail #2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/sealedInSameFile.kt b/backend.native/tests/external/codegen/blackbox/classes/sealedInSameFile.kt new file mode 100644 index 00000000000..673afef28ef --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/sealedInSameFile.kt @@ -0,0 +1,38 @@ +class B : A() + +sealed class A() { + constructor(i: Int): this() + + class C: A() +} + +object T : Y() + +class D : A(4) + +class E : A { + constructor(i: Int): super(i) + constructor(): super() +} + +object S : Z() + +sealed class Y : X() + +sealed class Z : Y() + +sealed class X : A() + +class Q : Y() + +fun box() : String { + B() + A.C() + D() + E() + E(4) + T + S + Q() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/classes/selfcreate.kt b/backend.native/tests/external/codegen/blackbox/classes/selfcreate.kt new file mode 100644 index 00000000000..95d67471511 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/selfcreate.kt @@ -0,0 +1,14 @@ +class B () {} + +open class A(val b : B) { + fun a(): A = object: A(b) {} +} + +fun box() : String { + val b = B() + val a = A(b).a() + + if (a.b !== b) return "failed" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/simpleBox.kt b/backend.native/tests/external/codegen/blackbox/classes/simpleBox.kt new file mode 100644 index 00000000000..be95d012d51 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/simpleBox.kt @@ -0,0 +1,8 @@ +class Box(t: T) { + var value = t +} + +fun box(): String { + val box: Box = Box(1) + return if (box.value == 1) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/classes/superConstructorCallWithComplexArg.kt b/backend.native/tests/external/codegen/blackbox/classes/superConstructorCallWithComplexArg.kt new file mode 100644 index 00000000000..1d2c6d4646a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/superConstructorCallWithComplexArg.kt @@ -0,0 +1,19 @@ +var log = "" + +open class Base(val s: String) + +class A(i: Int) : Base("O" + if (i == 23) { + log += "logged" + "K" +} +else { + "fail" +}) + +fun box(): String { + val result = A(23).s + if (result != "OK") return "fail: $result" + if (log != "logged") return "fail log: $log" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/classes/typedDelegation.kt b/backend.native/tests/external/codegen/blackbox/classes/typedDelegation.kt new file mode 100644 index 00000000000..e0b1241a6aa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/classes/typedDelegation.kt @@ -0,0 +1,31 @@ +interface A { + var zzzValue : T + fun zzz() : T +} + +class Base : A { + override var zzzValue : T? = null + + override fun zzz() : T? = zzzValue +} + +class X : A by Base() + +fun box() : String { + (Base() as A).zzz() + + if (X().zzz() != null) { + return "Fail" + } + + val x = X() + x.zzzValue = "aa" + if (x.zzzValue != "aa") { + return "Fail 2"; + } + if (x.zzz() != "aa") { + return "Fail 3"; + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/captureExtensionReceiver.kt b/backend.native/tests/external/codegen/blackbox/closures/captureExtensionReceiver.kt new file mode 100644 index 00000000000..bd78f48b9ef --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/captureExtensionReceiver.kt @@ -0,0 +1,40 @@ +interface B { + val bar: T +} + +fun String.foo() = object : B { + override val bar: String = length.toString() +} + +class C { + + fun String.extension() = this.length + + fun String.fooInClass() = object : B { + override val bar: String = extension().toString() + } + + fun String.fooInClassNoReceiver() = object : B { + override val bar: String = "123".extension().toString() + } + + fun fooInClass(s: String) = s.fooInClass().bar + + fun fooInClassNoReceiver(s: String) = s.fooInClassNoReceiver().bar +} + +fun box(): String { + var result = "Hello, world!".foo().bar + if (result != "13") return "fail 1: $result" + + result = C().fooInClass("Hello, world!") + + if (result != "13") return "fail 2: $result" + + result = C().fooInClassNoReceiver("Hello, world!") + + if (result != "3") return "fail 3: $result" + + return "OK" +} + diff --git a/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/captureFunctionInProperty.kt b/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/captureFunctionInProperty.kt new file mode 100644 index 00000000000..e2c507f3b28 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/captureFunctionInProperty.kt @@ -0,0 +1,15 @@ +interface T { + fun result(): String +} + +class A(val x: String) { + fun getx() = x + + fun foo() = object : T { + val bar = getx() + + override fun result() = bar + } +} + +fun box() = A("OK").foo().result() diff --git a/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/inFunction.kt b/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/inFunction.kt new file mode 100644 index 00000000000..7b4828fa7b5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/inFunction.kt @@ -0,0 +1,13 @@ +interface T { + fun result(): String +} + +class A(val x: String) { + fun foo() = object : T { + fun bar() = x + + override fun result() = bar() + } +} + +fun box() = A("OK").foo().result() diff --git a/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/inProperty.kt b/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/inProperty.kt new file mode 100644 index 00000000000..8f1846f7cfb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/inProperty.kt @@ -0,0 +1,13 @@ +interface T { + fun result(): String +} + +class A(val x: String) { + fun foo() = object : T { + val bar = x + + override fun result() = bar + } +} + +fun box() = A("OK").foo().result() diff --git a/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/inPropertyDeepObjectChain.kt b/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/inPropertyDeepObjectChain.kt new file mode 100644 index 00000000000..0bb07f581b9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/inPropertyDeepObjectChain.kt @@ -0,0 +1,18 @@ +interface T { + fun result(): String +} + +class A(val x: String) { + fun foo() = object : T { + fun bar() = object : T { + fun baz() = object : T { + val y = x + override fun result() = y + } + override fun result() = baz().result() + } + override fun result() = bar().result() + } +} + +fun box() = A("OK").foo().result() diff --git a/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/inPropertyFromSuperClass.kt b/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/inPropertyFromSuperClass.kt new file mode 100644 index 00000000000..2f7ff86a10c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/inPropertyFromSuperClass.kt @@ -0,0 +1,15 @@ +interface T { + fun result(): String +} + +open class B(val x: String) + +class A : B("OK") { + fun foo() = object : T { + val bar = x + + override fun result() = bar + } +} + +fun box() = A().foo().result() diff --git a/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/inPropertyFromSuperSuperClass.kt b/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/inPropertyFromSuperSuperClass.kt new file mode 100644 index 00000000000..3d600017d08 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/inPropertyFromSuperSuperClass.kt @@ -0,0 +1,17 @@ +interface T { + fun result(): String +} + +abstract class A(val x: Z) + +open class B : A("OK") + +class C : B() { + fun foo() = object : T { + val bar = x + + override fun result() = bar + } +} + +fun box() = C().foo().result() diff --git a/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/kt4176.kt b/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/kt4176.kt new file mode 100644 index 00000000000..129b3ad92c8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/kt4176.kt @@ -0,0 +1,17 @@ +open class Z(val s: Int) { + open fun a() {} +} + +class B(val x: Int) { + fun foo() { + class X : Z(x) { + + } + X() + } +} + +fun box(): String { + B(1).foo() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/kt4656.kt b/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/kt4656.kt new file mode 100644 index 00000000000..c3b93ff7efd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/captureOuterProperty/kt4656.kt @@ -0,0 +1,16 @@ +//KT-4656 Wrong capturing a function literal variable + +fun box(): String { + var foo = { 1 } + var bar = 1 + + val t = { "${foo()} $bar" } + fun b() = "${foo()} $bar" + + foo = { 2 } + bar = 2 + + if (t() != "2 2") return "fail1" + if (b() != "2 2") return "fail2" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/capturedLocalGenericFun.kt b/backend.native/tests/external/codegen/blackbox/closures/capturedLocalGenericFun.kt new file mode 100644 index 00000000000..ebe26220013 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/capturedLocalGenericFun.kt @@ -0,0 +1,14 @@ +fun box() : String { + + fun local(s : T) : T { + return s; + } + + fun test(s : Int) : Int { + return local(s) + } + + if (test(10) != 10) return "fail1" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/localFunInsideLocalFun.kt b/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/localFunInsideLocalFun.kt new file mode 100644 index 00000000000..106b0a763b3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/localFunInsideLocalFun.kt @@ -0,0 +1,13 @@ +fun box(): String { + fun rec(n : Int) { + fun x(m : Int) { + if (n > 0) rec(n - 1) + } + + x(0) + } + + rec(5) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/localFunInsideLocalFunDifferentSignatures.kt b/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/localFunInsideLocalFunDifferentSignatures.kt new file mode 100644 index 00000000000..38c08c8a19d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/localFunInsideLocalFunDifferentSignatures.kt @@ -0,0 +1,13 @@ +fun box(): String { + fun rec(n : Int) { + fun x(m : Int, k : Int) { + if (n > 0) rec(n - 1 + k) + } + + x(0, 0) + } + + rec(5) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/propertyAndFunctionNameClash.kt b/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/propertyAndFunctionNameClash.kt new file mode 100644 index 00000000000..94562f8c7f1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/propertyAndFunctionNameClash.kt @@ -0,0 +1,35 @@ +package d + +fun box(): String { + ListTag().test(listOf("a", "b")) + return "OK" +} + +fun ListTag.test(list: List) { + for (item in list) { + item() { + a { + text = item + } + } + } +} + +open class HtmlTag +open class ListTag : HtmlTag() {} +class LI : ListTag() {} + +public fun ListTag.item(body: LI.() -> Unit): Unit {} +fun HtmlTag.a(contents: A.() -> Unit) {} + +abstract class A : HtmlTag() { + public abstract var text: String +} + +fun listOf(vararg strings: String): List { + val list = ArrayList() + for (s in strings) { + list.add(s) + } + return list +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/threeLevels.kt b/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/threeLevels.kt new file mode 100644 index 00000000000..e0fc6457f26 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/threeLevels.kt @@ -0,0 +1,17 @@ +fun box(): String { + fun foo(x: Int) { + fun bar(y: Int) { + fun baz(z: Int) { + foo(x - 1) + } + + baz(y) + } + + if (x > 0) bar(x) + } + + foo(1) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/threeLevelsDifferentSignatures.kt b/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/threeLevelsDifferentSignatures.kt new file mode 100644 index 00000000000..a5fadc55936 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/threeLevelsDifferentSignatures.kt @@ -0,0 +1,16 @@ +fun box(): String { + fun foo(x: Int, s: String): String { + fun bar(y: Int) { + fun baz(z: Int, k: Int) { + foo(x - 1 + k, "Fail") + } + + baz(y, 0) + } + + if (x > 0) bar(x) + return s + } + + return foo(1, "OK") +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/varAsFunInsideLocalFun.kt b/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/varAsFunInsideLocalFun.kt new file mode 100644 index 00000000000..ec2ea57118e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/closureInsideClosure/varAsFunInsideLocalFun.kt @@ -0,0 +1,15 @@ +//KT-3276 + +fun box(): String { + fun rec(n : Int) { + val x = { m : Int -> + if (n > 0) rec(n - 1) + } + + x(0) + } + + rec(5) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/closureInsideConstrucor.kt b/backend.native/tests/external/codegen/blackbox/closures/closureInsideConstrucor.kt new file mode 100644 index 00000000000..38192dd47b0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/closureInsideConstrucor.kt @@ -0,0 +1,14 @@ +//adopted snippet from kdoc +open class KModel { + val sourcesInfo: String + init { + fun relativePath(psiFile: String): String { + return psiFile; + } + sourcesInfo = relativePath("OK") + } +} + +fun box():String { + return KModel().sourcesInfo; +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/closureOnTopLevel1.kt b/backend.native/tests/external/codegen/blackbox/closures/closureOnTopLevel1.kt new file mode 100644 index 00000000000..cc50b43b4a2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/closureOnTopLevel1.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +package test + +val p = { "OK" }() + +val getter: String + get() = { "OK" }() + +fun f() = { "OK" }() + +val obj = object : Function0 { + override fun invoke() = "OK" +} + +fun box(): String { + if (p != "OK") return "FAIL" + if (getter != "OK") return "FAIL" + if (f() != "OK") return "FAIL" + if (obj() != "OK") return "FAIL" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/closureOnTopLevel2.kt b/backend.native/tests/external/codegen/blackbox/closures/closureOnTopLevel2.kt new file mode 100644 index 00000000000..145e9c41fca --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/closureOnTopLevel2.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +val p = { "OK" }() + +val getter: String + get() = { "OK" }() + +fun f() = { "OK" }() + +val obj = object : Function0 { + override fun invoke() = "OK" +} + +fun box(): String { + if (p != "OK") return "FAIL" + if (getter != "OK") return "FAIL" + if (f() != "OK") return "FAIL" + if (obj() != "OK") return "FAIL" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/closureWithParameter.kt b/backend.native/tests/external/codegen/blackbox/closures/closureWithParameter.kt new file mode 100644 index 00000000000..6e5d15af401 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/closureWithParameter.kt @@ -0,0 +1,7 @@ +fun box() : String { + return apply( "OK", {arg: String -> arg } ) +} + +fun apply(arg : String, f : (p:String) -> String) : String { + return f(arg) +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/closureWithParameterAndBoxing.kt b/backend.native/tests/external/codegen/blackbox/closures/closureWithParameterAndBoxing.kt new file mode 100644 index 00000000000..a1a13fb62a6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/closureWithParameterAndBoxing.kt @@ -0,0 +1,7 @@ +fun box() : String { + return if (apply( 5, {arg: Int -> arg + 13 } ) == 18) "OK" else "fail" +} + +fun apply(arg : Int, f : (p:Int) -> Int) : Int { + return f(arg) +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/doubleEnclosedLocalVariable.kt b/backend.native/tests/external/codegen/blackbox/closures/doubleEnclosedLocalVariable.kt new file mode 100644 index 00000000000..96ac7f2ef19 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/doubleEnclosedLocalVariable.kt @@ -0,0 +1,8 @@ +fun box() : String { + val cl = 39 + return if (sum(200, { val ff = {cl}; ff() }) == 239) "OK" else "FAIL" +} + +fun sum(arg:Int, f : () -> Int) : Int { + return arg + f() +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/enclosingLocalVariable.kt b/backend.native/tests/external/codegen/blackbox/closures/enclosingLocalVariable.kt new file mode 100644 index 00000000000..01e1a103ff2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/enclosingLocalVariable.kt @@ -0,0 +1,8 @@ +fun box() : String { + val cl = 39 + return if (sum(200, { val m = { val r = { cl }; r() }; m() }) == 239) "OK" else "FAIL" +} + +fun sum(arg:Int, f : () -> Int) : Int { + return arg + f() +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/enclosingThis.kt b/backend.native/tests/external/codegen/blackbox/closures/enclosingThis.kt new file mode 100644 index 00000000000..787a4d89e4a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/enclosingThis.kt @@ -0,0 +1,12 @@ +class Point(val x:Int, val y:Int) { + fun mul() : (scalar:Int)->Point { + return { scalar:Int -> Point(x * scalar, y * scalar) } + } +} + +val m = Point(2, 3).mul() + +fun box() : String { + val answer = m(5) + return if (answer.x == 10 && answer.y == 15) "OK" else "FAIL" +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/extensionClosure.kt b/backend.native/tests/external/codegen/blackbox/closures/extensionClosure.kt new file mode 100644 index 00000000000..d4c73c7bcfe --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/extensionClosure.kt @@ -0,0 +1,13 @@ +class Point(val x : Int, val y : Int) + +fun box() : String { + val answer = apply(Point(3, 5), { scalar : Int -> + Point(x * scalar, y * scalar) + }) + + return if (answer.x == 6 && answer.y == 10) "OK" else "FAIL" +} + +fun apply(arg:Point, f : Point.(scalar : Int) -> Point) : Point { + return arg.f(2) +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/kt10044.kt b/backend.native/tests/external/codegen/blackbox/closures/kt10044.kt new file mode 100644 index 00000000000..277f356c76c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/kt10044.kt @@ -0,0 +1,41 @@ +open class JClass() { + fun test(): String { + return "OK" + } +} + +class Example : JClass { + constructor() : super() + + private var obj: JClass? = null + + var result: String? = null + + init { + { + result = obj?.test() + }() + } +} + +class Example2 : JClass { + constructor() : super() + + private var obj: JClass? = this + + var result: String? = null + + init { + { + result = obj?.test() + }() + } +} + + +fun box(): String { + val result = Example().result + if (result != null) "fail 1: $result" + + return Example2().result!! +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/kt11634.kt b/backend.native/tests/external/codegen/blackbox/closures/kt11634.kt new file mode 100644 index 00000000000..7bd1880718f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/kt11634.kt @@ -0,0 +1,27 @@ +interface A { + fun foo(): String +} + +class AImpl(val z: String) : A { + override fun foo(): String = z +} + +open class AFabric { + open fun createA(): A = AImpl("OK") +} + +class AWrapperFabric : AFabric() { + + override fun createA(): A { + return AImpl("fail") + } + + fun createMyA(): A { + return object : A by super.createA() { + } + } +} + +fun box(): String { + return AWrapperFabric().createMyA().foo() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/kt11634_2.kt b/backend.native/tests/external/codegen/blackbox/closures/kt11634_2.kt new file mode 100644 index 00000000000..1eb0e9ff096 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/kt11634_2.kt @@ -0,0 +1,27 @@ +interface A { + fun foo(): String +} + +class AImpl(val z: String) : A { + override fun foo(): String = z +} + +open class AFabric { + open fun createA(z: String): A = AImpl(z) +} + +class AWrapperFabric : AFabric() { + + override fun createA(z: String): A { + return AImpl("fail: $z") + } + + fun createMyA(): A { + val z = "OK" + return object : A by super.createA(z) {} + } +} + +fun box(): String { + return AWrapperFabric().createMyA().foo() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/kt11634_3.kt b/backend.native/tests/external/codegen/blackbox/closures/kt11634_3.kt new file mode 100644 index 00000000000..1fdaa65c236 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/kt11634_3.kt @@ -0,0 +1,27 @@ +interface A { + fun foo(): String +} + +class AImpl(val z: String) : A { + override fun foo(): String = z +} + +open class AFabric { + open fun createA(z: String): A = AImpl(z) +} + +class AWrapperFabric : AFabric() { + + override fun createA(z: String): A { + return AImpl("fail: $z") + } + + fun createMyA(): A { + val z = "OK" + return object : A by super@AWrapperFabric.createA(z) {} + } +} + +fun box(): String { + return AWrapperFabric().createMyA().foo() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/kt11634_4.kt b/backend.native/tests/external/codegen/blackbox/closures/kt11634_4.kt new file mode 100644 index 00000000000..08722aa81de --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/kt11634_4.kt @@ -0,0 +1,28 @@ +interface A { + fun foo(): String +} + +open class Base (val p: String) { + open val a = object : A { + override fun foo(): String { + return p + } + } +} + +open class Derived1 (p: String): Base(p) { + override open val a = object : A { + override fun foo(): String { + return "fail" + } + } + + inner class Derived2(p: String) : Base(p) { + val x = object : A by super@Derived1.a {} + } + +} + +fun box(): String { + return Derived1("OK").Derived2("fail").x.foo() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/kt2151.kt b/backend.native/tests/external/codegen/blackbox/closures/kt2151.kt new file mode 100644 index 00000000000..5b0da23f6ea --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/kt2151.kt @@ -0,0 +1,11 @@ +fun foo(): String { + return if (true) { + var x = "OK" + fun foo() { x += "fail" } + x + } else "fail" +} + +fun box(): String { + return foo() +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/kt3152.kt b/backend.native/tests/external/codegen/blackbox/closures/kt3152.kt new file mode 100644 index 00000000000..59bf3eaaeeb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/kt3152.kt @@ -0,0 +1,14 @@ +public class Test { + val content = 1 + inner class A { + val v = object { + fun f() = content + } + } +} + +fun box(): String { + Test().A() + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/kt3523.kt b/backend.native/tests/external/codegen/blackbox/closures/kt3523.kt new file mode 100644 index 00000000000..bbc225f8fd8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/kt3523.kt @@ -0,0 +1,18 @@ +open class Base { + fun doSomething() { + + } +} + +class X(val action: () -> Unit) { } + +class Foo : Base() { + inner class Bar() { + val x = X({ doSomething() }) + } +} + +fun box() : String { + Foo().Bar() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/kt3738.kt b/backend.native/tests/external/codegen/blackbox/closures/kt3738.kt new file mode 100644 index 00000000000..a05dbde0ae1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/kt3738.kt @@ -0,0 +1,19 @@ +class A { + fun foo() {} + fun bar(f: A.() -> Unit = {}) {} +} + +class B { + class D { + init { + A().bar { + this.foo() + } + } + } +} + +fun box(): String { + B.D() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/kt3905.kt b/backend.native/tests/external/codegen/blackbox/closures/kt3905.kt new file mode 100644 index 00000000000..fafd87700d3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/kt3905.kt @@ -0,0 +1,5 @@ +fun box() : String { + fun foo(t:() -> T) : T = t() + + return foo {"OK"} +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/kt4106.kt b/backend.native/tests/external/codegen/blackbox/closures/kt4106.kt new file mode 100644 index 00000000000..f190819f8d5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/kt4106.kt @@ -0,0 +1,15 @@ +class Foo(private val s: String) { + inner class Inner { + private val x = { + this@Foo.s + }() + } + + val f = Inner() + +} + +fun box(): String { + Foo("!") + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/kt4137.kt b/backend.native/tests/external/codegen/blackbox/closures/kt4137.kt new file mode 100644 index 00000000000..ea401a6fe80 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/kt4137.kt @@ -0,0 +1,13 @@ +open class A(val s: Int) { + +} + +infix fun Int.foo(s: Int): Int { + return this + s +} + +open class B : A({ 1 foo 2} ()) + +fun box(): String { + return if (B().s == 3) "OK" else "Fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/kt5589.kt b/backend.native/tests/external/codegen/blackbox/closures/kt5589.kt new file mode 100644 index 00000000000..3b3a27d91ca --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/kt5589.kt @@ -0,0 +1,5 @@ +fun box(): String { + val x = "OK" + fun bar(y: String = x): String = y + return bar() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/localClassFunClosure.kt b/backend.native/tests/external/codegen/blackbox/closures/localClassFunClosure.kt new file mode 100644 index 00000000000..ba0ae9734a0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/localClassFunClosure.kt @@ -0,0 +1,8 @@ +fun box(): String { + val o = "O" + fun ok() = o + "K" + class OK { + val ok = ok() + } + return OK().ok +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/localClassLambdaClosure.kt b/backend.native/tests/external/codegen/blackbox/closures/localClassLambdaClosure.kt new file mode 100644 index 00000000000..61fcbb61243 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/localClassLambdaClosure.kt @@ -0,0 +1,8 @@ +fun box(): String { + val o = "O" + val ok_L = {o + "K"} + class OK { + val ok = ok_L() + } + return OK().ok +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/localFunctionInFunction.kt b/backend.native/tests/external/codegen/blackbox/closures/localFunctionInFunction.kt new file mode 100644 index 00000000000..4639ab437dd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/localFunctionInFunction.kt @@ -0,0 +1,14 @@ +fun box(): String { + + fun local():Int { + return 10; + } + + class A { + fun test(): Int { + return local() + } + } + + return if (A().test() == 10) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/localFunctionInInitializer.kt b/backend.native/tests/external/codegen/blackbox/closures/localFunctionInInitializer.kt new file mode 100644 index 00000000000..6035aac60ad --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/localFunctionInInitializer.kt @@ -0,0 +1,12 @@ +fun box(): String { + + fun local():Int { + return 10; + } + + class A { + val test = local() + } + + return if (A().test == 10) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/localGenericFun.kt b/backend.native/tests/external/codegen/blackbox/closures/localGenericFun.kt new file mode 100644 index 00000000000..fe55a5834b5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/localGenericFun.kt @@ -0,0 +1,12 @@ +fun box() : String { + + fun local(s : T) : T { + return s; + } + + if (local(10) != 10) return "fail1" + + if (local("11") != "11") return "fail2" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/localReturn.kt b/backend.native/tests/external/codegen/blackbox/closures/localReturn.kt new file mode 100644 index 00000000000..cf6e749f41f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/localReturn.kt @@ -0,0 +1,19 @@ +fun box(): String { + val a = 1 + val explicitlyReturned = run1 f@{ + if (a > 0) + return@f "OK" + else "Fail 1" + } + if (explicitlyReturned != "OK") return explicitlyReturned + + val implicitlyReturned = run1 f@{ + if (a < 0) + return@f "Fail 2" + else "OK" + } + if (implicitlyReturned != "OK") return implicitlyReturned + return "OK" +} + +fun run1(f: () -> T): T { return f() } \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/localReturnWithAutolabel.kt b/backend.native/tests/external/codegen/blackbox/closures/localReturnWithAutolabel.kt new file mode 100644 index 00000000000..577f2100352 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/localReturnWithAutolabel.kt @@ -0,0 +1,19 @@ +fun box(): String { + val a = 1 + val explicitlyReturned = run1 { + if (a > 0) + return@run1 "OK" + else "Fail 1" + } + if (explicitlyReturned != "OK") return explicitlyReturned + + val implicitlyReturned = run1 { + if (a < 0) + return@run1 "Fail 2" + else "OK" + } + if (implicitlyReturned != "OK") return implicitlyReturned + return "OK" +} + +fun run1(f: () -> T): T { return f() } \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/closures/noRefToOuter.kt b/backend.native/tests/external/codegen/blackbox/closures/noRefToOuter.kt new file mode 100644 index 00000000000..366bfc3f5cc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/noRefToOuter.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class A { + fun f(): () -> String { + val s = "OK" + return { -> s } + } +} + +fun box(): String { + val lambdaClass = A().f().javaClass + val fields = lambdaClass.getDeclaredFields().toList() + if (fields.size != 1) return "Fail: lambda should only capture 's': $fields" + + val fieldName = fields[0].getName() + if (fieldName != "\$s") return "Fail: captured variable should be named '\$s': $fields" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/recursiveClosure.kt b/backend.native/tests/external/codegen/blackbox/closures/recursiveClosure.kt new file mode 100644 index 00000000000..25c8a6a86ce --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/recursiveClosure.kt @@ -0,0 +1,7 @@ +fun foo(s: String): String { + fun bar(count: Int): String = + if (count == 0) s else bar(count - 1) + return bar(10) +} + +fun box(): String = foo("OK") diff --git a/backend.native/tests/external/codegen/blackbox/closures/simplestClosure.kt b/backend.native/tests/external/codegen/blackbox/closures/simplestClosure.kt new file mode 100644 index 00000000000..7a9f3b439cf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/simplestClosure.kt @@ -0,0 +1,7 @@ +fun box() : String { + return invoker( {"OK"} ) +} + +fun invoker(gen : () -> String) : String { + return gen() +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/simplestClosureAndBoxing.kt b/backend.native/tests/external/codegen/blackbox/closures/simplestClosureAndBoxing.kt new file mode 100644 index 00000000000..50f22fbeb8d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/simplestClosureAndBoxing.kt @@ -0,0 +1,7 @@ +fun box() : String { + return if (int_invoker( { 7 } ) == 7) "OK" else "fail" +} + +fun int_invoker(gen : () -> Int) : Int { + return gen() +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/subclosuresWithinInitializers.kt b/backend.native/tests/external/codegen/blackbox/closures/subclosuresWithinInitializers.kt new file mode 100644 index 00000000000..3f76b76193e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/subclosuresWithinInitializers.kt @@ -0,0 +1,24 @@ +fun run(block: () -> R) = block() +inline fun inlineRun(block: () -> R) = block() + +class Outer(val outerProp: String) { + fun foo(arg: String): String { + class Local { + val work1 = run { outerProp + arg } + val work2 = inlineRun { outerProp + arg } + val obj = object : Any() { + override fun toString() = outerProp + arg + } + + override fun toString() = "${work1}#${work2}#${obj.toString()}" + } + + return Local().toString() + } +} + +fun box(): String { + val res = Outer("O").foo("K") + if (res != "OK#OK#OK") return "fail: $res" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/closures/underscoreParameters.kt b/backend.native/tests/external/codegen/blackbox/closures/underscoreParameters.kt new file mode 100644 index 00000000000..02b96fd24f0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/closures/underscoreParameters.kt @@ -0,0 +1,3 @@ +fun foo(block: (String, String, String) -> String): String = block("O", "fail", "K") + +fun box() = foo { x, _, y -> x + y } diff --git a/backend.native/tests/external/codegen/blackbox/collections/charSequence.kt b/backend.native/tests/external/codegen/blackbox/collections/charSequence.kt new file mode 100644 index 00000000000..2e7a8611009 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/charSequence.kt @@ -0,0 +1,70 @@ +// TARGET_BACKEND: JVM + +// FILE: J.java + +import java.util.*; + +public class J { + + public static class B extends A { + public int getLength() { return 456; } + public char get(int index) { + if (index == 1) return 'a'; + return super.get(index); + } + } + + public static String foo() { + B b = new B(); + CharSequence cs = (CharSequence) b; + + if (cs.length() != 456) return "fail 01"; + if (b.length() != 456) return "fail 02"; + if (b.getLength() != 456) return "fail 03"; + + if (cs.charAt(0) != 'z') return "fail 1"; + if (b.get(0) != 'z') return "fail 2"; + + if (cs.charAt(1) != 'a') return "fail 3"; + if (b.get(1) != 'a') return "fail 4"; + + return "OK"; + } +} + +// FILE: test.kt + +open class A : CharSequence { + override val length: Int = 123 + + override fun get(index: Int) = 'z'; + + override fun subSequence(start: Int, end: Int): CharSequence { + throw UnsupportedOperationException() + } +} + +fun box(): String { + val b = J.B() + val a = A() + + if (b[0] != 'z') return "fail 6" + if (a[0] != 'z') return "fail 7" + if (b[1] != 'a') return "fail 8" + if (a[0] != 'z') return "fail 9" + + if (b.get(0) != 'z') return "fail 10" + if (a.get(0) != 'z') return "fail 11" + if (b.get(1) != 'a') return "fail 12" + if (a.get(1) != 'z') return "fail 13" + + var cs: CharSequence = a + if (a.length != 123) return "fail 14" + if (cs.length != 123) return "fail 15" + + cs = b + if (b.length != 456) return "fail 16" + if (b.length != 456) return "fail 17" + + return J.foo(); +} diff --git a/backend.native/tests/external/codegen/blackbox/collections/implementCollectionThroughKotlin.kt b/backend.native/tests/external/codegen/blackbox/collections/implementCollectionThroughKotlin.kt new file mode 100644 index 00000000000..036eb71f713 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/implementCollectionThroughKotlin.kt @@ -0,0 +1,97 @@ +// TARGET_BACKEND: JVM + +// FILE: J.java + +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +public class J extends MyList { + @Override + public int getSize() { + return 55; + } + + @Override + public int lastIndexOf(String s) { + return 0; + } + + @Override + public int indexOf(String s) { + return 0; + } + + @Override + public boolean contains(String s) { + return true; + } + + @Override + public boolean isEmpty() { + return false; + } + + @NotNull + @Override + public Iterator iterator() { + return null; + } + + @Override + public boolean containsAll(Collection c) { + return false; + } + + @Override + public String get(int index) { + return null; + } + + @Override + public List subList(int i, int i1) { + return super.subList(i, i1); + } + + @Override + public ListIterator listIterator(int i) { + return super.listIterator(i); + } + + @Override + public ListIterator listIterator() { + return super.listIterator(); + } +} + +// FILE: test.kt + +abstract class MyList : List + +class ListImpl : J() { + override val size: Int get() = super.size + 1 +} + +fun box(): String { + val impl = ListImpl() + if (impl.size != 56) return "fail 1" + if (!impl.contains("abc")) return "fail 2" + + val l: List = impl + + if (l.size != 56) return "fail 3" + if (!l.contains("abc")) return "fail 4" + + val anyList: List = impl as List + + if (anyList.size != 56) return "fail 5" + if (!anyList.contains("abc")) return "fail 6" + + if (anyList.contains(1)) return "fail 7" + if (anyList.contains(null)) return "fail 8" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/collections/inSetWithSmartCast.kt b/backend.native/tests/external/codegen/blackbox/collections/inSetWithSmartCast.kt new file mode 100644 index 00000000000..ee4987608d6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/inSetWithSmartCast.kt @@ -0,0 +1,15 @@ +// WITH_RUNTIME + +fun contains(set: Set, x: Int): Boolean = when { + set.size == 0 -> false + else -> x in set as Set +} + +fun box(): String { + val set = setOf(1) + if (contains(set, 1)) { + return "OK" + } + + return "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/collections/irrelevantImplCharSequence.kt b/backend.native/tests/external/codegen/blackbox/collections/irrelevantImplCharSequence.kt new file mode 100644 index 00000000000..ebabbd76ec2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/irrelevantImplCharSequence.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: J.java + +public class J { + abstract static public class AImpl { + public char charAt(int index) { + return 'A'; + } + + public final int length() { return 56; } + } + + public static class A extends AImpl implements CharSequence { + public CharSequence subSequence(int start, int end) { + return null; + } + } +} + +// FILE: test.kt + +class X : J.A() + +fun box(): String { + val x = X() + if (x.length != 56) return "fail 1" + if (x[0] != 'A') return "fail 2" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/collections/irrelevantImplCharSequenceKotlin.kt b/backend.native/tests/external/codegen/blackbox/collections/irrelevantImplCharSequenceKotlin.kt new file mode 100644 index 00000000000..83900da8bf0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/irrelevantImplCharSequenceKotlin.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: J.java + +public class J { + public static class A extends AImpl implements CharSequence { + public CharSequence subSequence(int start, int end) { + return null; + } + } +} + +// FILE: test.kt + +abstract class AImpl { + fun charAt(index: Int): Char { + return 'A' + } + + fun length(): Int { + return 56 + } +} + +class X : J.A() + +fun box(): String { + val x = X() + if (x.length != 56) return "fail 1" + if (x[0] != 'A') return "fail 2" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/collections/irrelevantImplMutableList.kt b/backend.native/tests/external/codegen/blackbox/collections/irrelevantImplMutableList.kt new file mode 100644 index 00000000000..353ad6ab61d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/irrelevantImplMutableList.kt @@ -0,0 +1,115 @@ +// TARGET_BACKEND: JVM + +// FILE: J.java + +import java.util.*; +public class J { + abstract static public class AImpl { + public final int size() { + return 56; + } + + public boolean isEmpty() { + return false; + } + + public final boolean contains(Object o) { + return true; + } + + public Iterator iterator() { + return null; + } + + public Object[] toArray() { + return new Object[0]; + } + + public T[] toArray(T[] a) { + return null; + } + + public boolean add(String s) { + return false; + } + + public boolean remove(Object o) { + return false; + } + + public boolean containsAll(Collection c) { + return false; + } + + public boolean addAll(Collection c) { + return false; + } + + public boolean addAll(int index, Collection c) { + return false; + } + + public boolean removeAll(Collection c) { + return false; + } + + public boolean retainAll(Collection c) { + return false; + } + + public void clear() { + + } + + public String get(int index) { + return null; + } + + public String set(int index, String element) { + return null; + } + + public void add(int index, String element) { + + } + + public String remove(int index) { + return null; + } + + public int indexOf(Object o) { + return 0; + } + + public int lastIndexOf(Object o) { + return 0; + } + + public ListIterator listIterator() { + return null; + } + + public ListIterator listIterator(int index) { + return null; + } + + public List subList(int fromIndex, int toIndex) { + return null; + } + } + + public static class A extends AImpl implements List { + } +} + +// FILE: test.kt + +class X : J.A() + +fun box(): String { + val x = X() + if (x.size != 56) return "fail 1" + if (!x.contains("")) return "fail 2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/collections/irrelevantImplMutableListKotlin.kt b/backend.native/tests/external/codegen/blackbox/collections/irrelevantImplMutableListKotlin.kt new file mode 100644 index 00000000000..d99b4ea8ec1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/irrelevantImplMutableListKotlin.kt @@ -0,0 +1,105 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: A.java + +public class A extends AImpl implements java.util.List { + public T[] toArray(T[] a) {return null;} + public Object[] toArray() {return null;} +} + +// FILE: test.kt + +public abstract class AImpl { + fun add(element: String): Boolean { + throw UnsupportedOperationException() + } + + fun remove(element: Any?): Boolean { + throw UnsupportedOperationException() + } + + @JvmSuppressWildcards(suppress = false) + fun addAll(elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + fun addAll(index: Int, elements: Collection<@JvmWildcard String>): Boolean { + throw UnsupportedOperationException() + } + + fun removeAll(elements: Collection<*>): Boolean { + throw UnsupportedOperationException() + } + + fun retainAll(elements: Collection<*>): Boolean { + throw UnsupportedOperationException() + } + + fun clear() { + throw UnsupportedOperationException() + } + + fun set(index: Int, element: String): String { + throw UnsupportedOperationException() + } + + fun add(index: Int, element: String) { + throw UnsupportedOperationException() + } + + fun remove(index: Int): String { + throw UnsupportedOperationException() + } + + fun listIterator(): MutableListIterator { + throw UnsupportedOperationException() + } + + fun listIterator(index: Int): MutableListIterator { + throw UnsupportedOperationException() + } + + fun subList(fromIndex: Int, toIndex: Int): MutableList { + throw UnsupportedOperationException() + } + + fun size(): Int = 56 + + fun isEmpty(): Boolean { + throw UnsupportedOperationException() + } + + fun contains(element: Any?) = true + + fun containsAll(elements: Collection<*>): Boolean { + throw UnsupportedOperationException() + } + + fun get(index: Int): String { + throw UnsupportedOperationException() + } + + fun indexOf(element: Any?): Int { + throw UnsupportedOperationException() + } + + fun lastIndexOf(element: Any?): Int { + throw UnsupportedOperationException() + } + + fun iterator(): MutableIterator { + throw UnsupportedOperationException() + } +} + + +class X : A() + +fun box(): String { + val x = X() + if (x.size != 56) return "fail 1" + if (!x.contains("")) return "fail 2" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/collections/irrelevantImplMutableListSubstitution.kt b/backend.native/tests/external/codegen/blackbox/collections/irrelevantImplMutableListSubstitution.kt new file mode 100644 index 00000000000..6e60e2782f2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/irrelevantImplMutableListSubstitution.kt @@ -0,0 +1,115 @@ +// TARGET_BACKEND: JVM + +// FILE: J.java + +import java.util.*; +public class J { + abstract static public class AImpl { + public int size() { + return 56; + } + + public boolean isEmpty() { + return false; + } + + public final boolean contains(Object o) { + return true; + } + + public Iterator iterator() { + return null; + } + + public Object[] toArray() { + return new Object[0]; + } + + public T[] toArray(T[] a) { + return null; + } + + public boolean add(E s) { + return false; + } + + public boolean remove(Object o) { + return false; + } + + public boolean containsAll(Collection c) { + return false; + } + + public boolean addAll(Collection c) { + return false; + } + + public boolean addAll(int index, Collection c) { + return false; + } + + public boolean removeAll(Collection c) { + return false; + } + + public boolean retainAll(Collection c) { + return false; + } + + public void clear() { + + } + + public E get(int index) { + return null; + } + + public E set(int index, E element) { + return null; + } + + public void add(int index, E element) { + + } + + public E remove(int index) { + return null; + } + + public int indexOf(Object o) { + return 0; + } + + public int lastIndexOf(Object o) { + return 0; + } + + public ListIterator listIterator() { + return null; + } + + public ListIterator listIterator(int index) { + return null; + } + + public List subList(int fromIndex, int toIndex) { + return null; + } + } + + public static class A extends AImpl implements List { + } +} + +// FILE: test.kt + +class X : J.A() + +fun box(): String { + val x = X() + if (x.size != 56) return "fail 1" + if (!x.contains(null)) return "fail 2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/collections/irrelevantRemoveAtOverrideInJava.kt b/backend.native/tests/external/codegen/blackbox/collections/irrelevantRemoveAtOverrideInJava.kt new file mode 100644 index 00000000000..41af923e660 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/irrelevantRemoveAtOverrideInJava.kt @@ -0,0 +1,112 @@ +// TARGET_BACKEND: JVM + +// FILE: J.java + +import java.util.*; + +public class J implements Container { + final public String removeAt(int index) { return "abc"; } +} + +// FILE: test.kt + +interface Container { + fun removeAt(x: Int): String +} + +class A : J(), MutableList { + override fun isEmpty(): Boolean { + throw UnsupportedOperationException() + } + + override val size: Int + get() = throw UnsupportedOperationException() + + override fun contains(element: String): Boolean { + throw UnsupportedOperationException() + } + + override fun containsAll(elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun get(index: Int): String { + throw UnsupportedOperationException() + } + + override fun indexOf(element: String): Int { + throw UnsupportedOperationException() + } + + override fun lastIndexOf(element: String): Int { + throw UnsupportedOperationException() + } + + override fun add(element: String): Boolean { + throw UnsupportedOperationException() + } + + override fun remove(element: String): Boolean { + throw UnsupportedOperationException() + } + + override fun addAll(elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun addAll(index: Int, elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun removeAll(elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun retainAll(elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun clear() { + throw UnsupportedOperationException() + } + + override fun set(index: Int, element: String): String { + throw UnsupportedOperationException() + } + + override fun add(index: Int, element: String) { + throw UnsupportedOperationException() + } + + override fun listIterator(): MutableListIterator { + throw UnsupportedOperationException() + } + + override fun listIterator(index: Int): MutableListIterator { + throw UnsupportedOperationException() + } + + override fun subList(fromIndex: Int, toIndex: Int): MutableList { + throw UnsupportedOperationException() + } + + override fun iterator(): MutableIterator { + throw UnsupportedOperationException() + } +} + +fun box(): String { + val a = A() + if (a.removeAt(0) != "abc") return "fail 1" + + val l: MutableList = a + if (l.removeAt(0) != "abc") return "fail 2" + + val anyList: MutableList = a as MutableList + if (anyList.removeAt(0) != "abc") return "fail 3" + + val container: Container = a + if (container.removeAt(0) != "abc") return "fail 4" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/collections/irrelevantSizeOverrideInJava.kt b/backend.native/tests/external/codegen/blackbox/collections/irrelevantSizeOverrideInJava.kt new file mode 100644 index 00000000000..b3d1023d3c7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/irrelevantSizeOverrideInJava.kt @@ -0,0 +1,46 @@ +// TARGET_BACKEND: JVM + +// FILE: J.java + +import java.util.*; + +public class J implements Sized { + final public int getSize() { return 123; } +} + +// FILE: test.kt + +interface Sized { + val size: Int +} + +class A : J(), Collection { + override fun isEmpty(): Boolean { + throw UnsupportedOperationException() + } + + override fun contains(element: T): Boolean { + throw UnsupportedOperationException() + } + + override fun iterator(): Iterator { + throw UnsupportedOperationException() + } + + override fun containsAll(elements: Collection): Boolean { + throw UnsupportedOperationException() + } +} + +fun box(): String { + val a = A() + if (a.size != 123) return "fail 1" + + val c: Collection = a + if (c.size != 123) return "fail 2" + + val sized: Sized = a + if (sized.size != 123) return "fail 3" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/collections/mutableList.kt b/backend.native/tests/external/codegen/blackbox/collections/mutableList.kt new file mode 100644 index 00000000000..8941b444032 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/mutableList.kt @@ -0,0 +1,101 @@ +// TARGET_BACKEND: JVM + +// FILE: J.java + +import java.util.*; + +public class J { + + private static class MyList extends KList {} + + public static String foo() { + Collection collection = new MyList(); + if (!collection.contains("ABCDE")) return "fail 1"; + if (!collection.containsAll(Arrays.asList(1, 2, 3))) return "fail 2"; + return "OK"; + } +} + +// FILE: test.kt + +open class KList : MutableList { + override fun add(e: E): Boolean { + throw UnsupportedOperationException() + } + + override fun remove(o: E): Boolean { + throw UnsupportedOperationException() + } + + override fun addAll(c: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun addAll(index: Int, c: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun removeAll(c: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun retainAll(c: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun clear() { + throw UnsupportedOperationException() + } + + override fun set(index: Int, element: E): E { + throw UnsupportedOperationException() + } + + override fun add(index: Int, element: E) { + throw UnsupportedOperationException() + } + + override fun removeAt(index: Int): E { + throw UnsupportedOperationException() + } + + override fun listIterator(): MutableListIterator { + throw UnsupportedOperationException() + } + + override fun listIterator(index: Int): MutableListIterator { + throw UnsupportedOperationException() + } + + override fun subList(fromIndex: Int, toIndex: Int): MutableList { + throw UnsupportedOperationException() + } + + override fun iterator(): MutableIterator { + throw UnsupportedOperationException() + } + + override val size: Int + get() = throw UnsupportedOperationException() + + override fun isEmpty(): Boolean { + throw UnsupportedOperationException() + } + + override fun contains(o: E) = true + override fun containsAll(c: Collection) = true + + override fun get(index: Int): E { + throw UnsupportedOperationException() + } + + override fun indexOf(o: E): Int { + throw UnsupportedOperationException() + } + + override fun lastIndexOf(o: E): Int { + throw UnsupportedOperationException() + } +} + +fun box() = J.foo() diff --git a/backend.native/tests/external/codegen/blackbox/collections/noStubsInJavaSuperClass.kt b/backend.native/tests/external/codegen/blackbox/collections/noStubsInJavaSuperClass.kt new file mode 100644 index 00000000000..c884c5cdeb3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/noStubsInJavaSuperClass.kt @@ -0,0 +1,69 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: B.java +public abstract class B extends A implements L { + public String callIndexAdd(int x) { + add(0, null); + return null; + } +} + +// FILE: main.kt +open class A : Collection { + override val size: Int + get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates. + + override fun contains(element: T): Boolean { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun containsAll(elements: Collection): Boolean { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun isEmpty(): Boolean { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun iterator(): Iterator { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } +} + +interface L : List + +// 'add(Int; Object)' method must be present in C though it has supeclass that is subclass of List +class C : B() { + override fun get(index: Int): F { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun indexOf(element: F): Int { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun lastIndexOf(element: F): Int { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun listIterator(): ListIterator { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun listIterator(index: Int): ListIterator { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun subList(fromIndex: Int, toIndex: Int): List { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } +} + +fun box() = try { + C().callIndexAdd(1) + throw RuntimeException("fail 1") +} catch (e: UnsupportedOperationException) { + if (e.message != "Operation is not supported for read-only collection") throw RuntimeException("fail 2") + "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/collections/platformValueContains.kt b/backend.native/tests/external/codegen/blackbox/collections/platformValueContains.kt new file mode 100644 index 00000000000..14d2cece53c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/platformValueContains.kt @@ -0,0 +1,54 @@ +// TARGET_BACKEND: JVM + +// FILE: J.java + +import java.util.*; + +public class J { + public static String nullValue() { + return null; + } +} + +// FILE: test.kt + +class MySet : Set { + override val size: Int + get() = throw UnsupportedOperationException() + + override fun isEmpty(): Boolean { + throw UnsupportedOperationException() + } + + override fun contains(o: String): Boolean { + throw UnsupportedOperationException() + } + + override fun iterator(): Iterator { + throw UnsupportedOperationException() + } + + override fun containsAll(c: Collection): Boolean { + throw UnsupportedOperationException() + } +} + +fun box(): String { + val mySet = MySet() + + // no UnsupportedOperationException thrown + mySet.contains(J.nullValue()) + J.nullValue() in mySet + + val set: Set = mySet + set.contains(J.nullValue()) + J.nullValue() in set + + val anySet: Set = mySet as Set + anySet.contains(J.nullValue()) + anySet.contains(null) + J.nullValue() in anySet + null in anySet + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/collections/readOnlyList.kt b/backend.native/tests/external/codegen/blackbox/collections/readOnlyList.kt new file mode 100644 index 00000000000..041ec52be0b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/readOnlyList.kt @@ -0,0 +1,60 @@ +// TARGET_BACKEND: JVM + +// FILE: J.java + +import java.util.*; + +public class J { + + private static class MyList extends KList {} + + public static String foo() { + Collection collection = new MyList(); + if (!collection.contains("ABCDE")) return "fail 1"; + if (!collection.containsAll(Arrays.asList(1, 2, 3))) return "fail 2"; + return "OK"; + } +} + +// FILE: test.kt + +open class KList : List { + override val size: Int + get() = throw UnsupportedOperationException() + + override fun isEmpty(): Boolean { + throw UnsupportedOperationException() + } + override fun contains(o: E) = true + override fun containsAll(c: Collection) = true + + override fun iterator(): Iterator { + throw UnsupportedOperationException() + } + + override fun get(index: Int): E { + throw UnsupportedOperationException() + } + + override fun indexOf(element: E): Int { + throw UnsupportedOperationException() + } + + override fun lastIndexOf(element: E): Int { + throw UnsupportedOperationException() + } + + override fun listIterator(): ListIterator { + throw UnsupportedOperationException() + } + + override fun listIterator(index: Int): ListIterator { + throw UnsupportedOperationException() + } + + override fun subList(fromIndex: Int, toIndex: Int): List { + throw UnsupportedOperationException() + } +} + +fun box() = J.foo() diff --git a/backend.native/tests/external/codegen/blackbox/collections/readOnlyMap.kt b/backend.native/tests/external/codegen/blackbox/collections/readOnlyMap.kt new file mode 100644 index 00000000000..89fd8d60c90 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/readOnlyMap.kt @@ -0,0 +1,44 @@ +// TARGET_BACKEND: JVM + +// FILE: J.java + +import java.util.*; + +public class J { + + private static class MyMap extends KMap {} + + public static String foo() { + Map collection = new MyMap(); + if (!collection.containsKey("ABCDE")) return "fail 1"; + if (!collection.containsValue(1)) return "fail 2"; + return "OK"; + } +} + +// FILE: test.kt + +open class KMap : Map { + override val size: Int + get() = throw UnsupportedOperationException() + + override fun isEmpty(): Boolean { + throw UnsupportedOperationException() + } + + override fun containsKey(key: K) = true + override fun containsValue(value: V) = true + + override fun get(key: K): V? { + throw UnsupportedOperationException() + } + + override val keys: Set + get() = throw UnsupportedOperationException() + override val values: Collection + get() = throw UnsupportedOperationException() + override val entries: Set> + get() = throw UnsupportedOperationException() +} + +fun box() = J.foo() diff --git a/backend.native/tests/external/codegen/blackbox/collections/removeAtInt.kt b/backend.native/tests/external/codegen/blackbox/collections/removeAtInt.kt new file mode 100644 index 00000000000..8cb05571d02 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/removeAtInt.kt @@ -0,0 +1,106 @@ +// TARGET_BACKEND: JVM + +// FILE: J.java + +import java.util.*; + +public class J { + + private static class MyList extends A {} + + public static String foo() { + MyList myList = new MyList(); + List list = (List) myList; + + if (!list.remove((Integer) 1)) return "fail 1"; + if (list.remove((int) 1) != 123) return "fail 2"; + + if (!myList.remove((Integer) 1)) return "fail 3"; + if (myList.remove((int) 1) != 123) return "fail 4"; + + if (myList.removeAt(1) != 123) return "fail 5"; + return "OK"; + } +} + +// FILE: test.kt + +open class A : MutableList { + override val size: Int + get() = throw UnsupportedOperationException() + override fun isEmpty(): Boolean = throw UnsupportedOperationException() + + override fun contains(o: Int): Boolean { + throw UnsupportedOperationException() + } + + override fun containsAll(c: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun get(index: Int): Int { + throw UnsupportedOperationException() + } + + override fun indexOf(o: Int): Int { + throw UnsupportedOperationException() + } + + override fun lastIndexOf(o: Int): Int { + throw UnsupportedOperationException() + } + + override fun add(e: Int): Boolean { + throw UnsupportedOperationException() + } + + override fun remove(o: Int) = true + + override fun removeAt(index: Int): Int = 123 + + override fun addAll(c: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun addAll(index: Int, c: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun removeAll(c: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun retainAll(c: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun clear() { + throw UnsupportedOperationException() + } + + override fun set(index: Int, element: Int): Int { + throw UnsupportedOperationException() + } + + override fun add(index: Int, element: Int) { + throw UnsupportedOperationException() + } + + override fun listIterator(): MutableListIterator { + throw UnsupportedOperationException() + } + + override fun listIterator(index: Int): MutableListIterator { + throw UnsupportedOperationException() + } + + override fun subList(fromIndex: Int, toIndex: Int): MutableList { + throw UnsupportedOperationException() + } + + override fun iterator(): MutableIterator { + throw UnsupportedOperationException() + } +} + +fun box() = J.foo() diff --git a/backend.native/tests/external/codegen/blackbox/collections/strList.kt b/backend.native/tests/external/codegen/blackbox/collections/strList.kt new file mode 100644 index 00000000000..b6d42fdbaff --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/strList.kt @@ -0,0 +1,101 @@ +// TARGET_BACKEND: JVM + +// FILE: J.java + +import java.util.*; + +public class J { + + private static class MyList extends KList {} + + public static String foo() { + Collection collection = new MyList(); + if (!collection.contains("ABCDE")) return "fail 1"; + if (!collection.containsAll(Arrays.asList(1, 2, 3))) return "fail 2"; + return "OK"; + } +} + +// FILE: test.kt + +abstract class KList : MutableList { + override val size: Int + get() = throw UnsupportedOperationException() + + override fun isEmpty(): Boolean { + throw UnsupportedOperationException() + } + + override fun contains(o: String) = true + override fun containsAll(c: Collection) = true + + override fun get(index: Int): String { + throw UnsupportedOperationException() + } + + override fun indexOf(o: String): Int { + throw UnsupportedOperationException() + } + + override fun lastIndexOf(o: String): Int { + throw UnsupportedOperationException() + } + + override fun iterator(): MutableIterator { + throw UnsupportedOperationException() + } + + override fun add(e: String): Boolean { + throw UnsupportedOperationException() + } + + override fun remove(o: String): Boolean { + throw UnsupportedOperationException() + } + + override fun addAll(c: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun addAll(index: Int, c: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun removeAll(c: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun retainAll(c: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun clear() { + throw UnsupportedOperationException() + } + + override fun set(index: Int, element: String): String { + throw UnsupportedOperationException() + } + + override fun add(index: Int, element: String) { + throw UnsupportedOperationException() + } + + override fun removeAt(index: Int): String { + throw UnsupportedOperationException() + } + + override fun listIterator(): MutableListIterator { + throw UnsupportedOperationException() + } + + override fun listIterator(index: Int): MutableListIterator { + throw UnsupportedOperationException() + } + + override fun subList(fromIndex: Int, toIndex: Int): MutableList { + throw UnsupportedOperationException() + } + +} +fun box() = J.foo() diff --git a/backend.native/tests/external/codegen/blackbox/collections/toArrayInJavaClass.kt b/backend.native/tests/external/codegen/blackbox/collections/toArrayInJavaClass.kt new file mode 100644 index 00000000000..ac984435cda --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/collections/toArrayInJavaClass.kt @@ -0,0 +1,35 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: B.java +public class B extends A { + @Override + public T[] toArray(T[] a) { + return a; + } +} + +// FILE: main.kt +open class A : Collection { + override val size: Int + get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates. + + override fun contains(element: T): Boolean { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun containsAll(elements: Collection): Boolean { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun isEmpty(): Boolean { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun iterator(): Iterator { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } +} + +fun box() = B().toArray(arrayOf("OK"))[0] diff --git a/backend.native/tests/external/codegen/blackbox/compatibility/dataClassEqualsHashCodeToString.kt b/backend.native/tests/external/codegen/blackbox/compatibility/dataClassEqualsHashCodeToString.kt new file mode 100644 index 00000000000..c0fd15fad4d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/compatibility/dataClassEqualsHashCodeToString.kt @@ -0,0 +1,13 @@ +// LANGUAGE_VERSION: 1.0 + +data class Foo(val s: String) + +fun box(): String { + val f1 = Foo("OK") + val f2 = Foo("OK") + if (f1 != f2) return "Fail equals" + if (f1.hashCode() != f2.hashCode()) return "Fail hashCode" + if (f1.toString() != f2.toString() || f1.toString() != "Foo(s=OK)") return "Fail toString: $f1 $f2" + + return f1.s +} diff --git a/backend.native/tests/external/codegen/blackbox/constants/constantsInWhen.kt b/backend.native/tests/external/codegen/blackbox/constants/constantsInWhen.kt new file mode 100644 index 00000000000..cbc39e03146 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/constants/constantsInWhen.kt @@ -0,0 +1,18 @@ +fun test( + b: Boolean, + i: Int +) { + if (b) { + when (i) { + 0 -> foo(1) + else -> null + } + } else null +} + +fun foo(i: Int) = i + +fun box(): String { + test(true, 1) + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/constants/float.kt b/backend.native/tests/external/codegen/blackbox/constants/float.kt new file mode 100644 index 00000000000..5c60d382df1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/constants/float.kt @@ -0,0 +1,18 @@ +fun box(): String { + if (1F != 1.toFloat()) return "fail 1" + if (1.0F != 1.0.toFloat()) return "fail 2" + if (1e1F != 1e1.toFloat()) return "fail 3" + if (1.0e1F != 1.0e1.toFloat()) return "fail 4" + if (1e-1F != 1e-1.toFloat()) return "fail 5" + if (1.0e-1F != 1.0e-1.toFloat()) return "fail 6" + + if (1f != 1.toFloat()) return "fail 7" + if (1.0f != 1.0.toFloat()) return "fail 8" + if (1e1f != 1e1.toFloat()) return "fail 9" + if (1.0e1f != 1.0e1.toFloat()) return "fail 10" + if (1e-1f != 1e-1.toFloat()) return "fail 11" + if (1.0e-1f != 1.0e-1.toFloat()) return "fail 12" + + return "OK" +} + diff --git a/backend.native/tests/external/codegen/blackbox/constants/kt9532.kt b/backend.native/tests/external/codegen/blackbox/constants/kt9532.kt new file mode 100644 index 00000000000..e600cc309c1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/constants/kt9532.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +object A { + const val a: String = "$" + const val b = "1234$a" + const val c = 10000 + + val bNonConst = "1234$a" + val bNullable: String = "1234$a" +} + +object B { + const val a: String = "$" + const val b = "1234$a" + const val c = 10000 + + val bNonConst = "1234$a" + val bNullable: String = "1234$a" +} + +fun box(): String { + if (A.a !== B.a) return "Fail 1: A.a !== B.a" + + if (A.b !== B.b) return "Fail 2: A.b !== B.b" + + if (A.c !== B.c) return "Fail 3: A.c !== B.c" + + if (A.bNonConst === B.bNonConst) return "Fail 5: A.bNonConst == B.bNonConst" + if (A.bNullable === B.bNullable) return "Fail 6: A.bNullable == B.bNullable" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/constants/long.kt b/backend.native/tests/external/codegen/blackbox/constants/long.kt new file mode 100644 index 00000000000..7fa2eaf4f50 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/constants/long.kt @@ -0,0 +1,10 @@ +fun box(): String { + if (1L != 1.toLong()) return "fail 1" + if (0x1L != 0x1.toLong()) return "fail 2" + if (0X1L != 0X1.toLong()) return "fail 3" + if (0b1L != 0b1.toLong()) return "fail 4" + if (0B1L != 0B1.toLong()) return "fail 5" + + return "OK" +} + diff --git a/backend.native/tests/external/codegen/blackbox/constants/privateConst.kt b/backend.native/tests/external/codegen/blackbox/constants/privateConst.kt new file mode 100644 index 00000000000..041cc94e9fd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/constants/privateConst.kt @@ -0,0 +1,7 @@ +private const val z = "OK"; + +fun box(): String { + return { + z + }() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/bottles.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/bottles.kt new file mode 100644 index 00000000000..2d376593843 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/bottles.kt @@ -0,0 +1,9 @@ +fun box(): String { + var bottles = 99 + while (bottles > 0) { + // System.out.println("bottles of beer on the wall"); + bottles -= 1 + bottles-- + } + return if (bottles == -1) "OK" else "Fail $bottles" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/breakFromOuter.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/breakFromOuter.kt new file mode 100644 index 00000000000..4890505afd0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/breakFromOuter.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + OUTER@while (true) { + var x = "" + try { + do { + x = x + break@OUTER + } while (true) + } finally { + return "OK" + } + } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/breakInDoWhile.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/breakInDoWhile.kt new file mode 100644 index 00000000000..cd932454965 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/breakInDoWhile.kt @@ -0,0 +1,10 @@ +fun box(): String { + val ok: String? = "OK" + var res = "" + + do { + res += ok ?: break + } while (false) + + return res +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/breakInExpr.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/breakInExpr.kt new file mode 100644 index 00000000000..203452b0a60 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/breakInExpr.kt @@ -0,0 +1,9 @@ +fun test(str: String): String { + var s = "" + for (i in 1..3) { + s += if (i<2) str else break + } + return s +} + +fun box(): String = test("OK") \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/continueInDoWhile.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/continueInDoWhile.kt new file mode 100644 index 00000000000..d46fe01fd97 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/continueInDoWhile.kt @@ -0,0 +1,6 @@ +fun box(): String { + var i = 0 + do continue while (i++ < 3) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/continueInExpr.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/continueInExpr.kt new file mode 100644 index 00000000000..667cd474bd0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/continueInExpr.kt @@ -0,0 +1,7 @@ +fun box(): String { + var s = "OK" + for (i in 1..3) { + s = s + if (i<2) "" else continue + } + return s +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/inlineWithStack.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/inlineWithStack.kt new file mode 100644 index 00000000000..7c5b904df3e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/inlineWithStack.kt @@ -0,0 +1,17 @@ +inline fun bar(block: () -> String) : String { + return block() +} + +inline fun bar2() : String { + while (true) break + return bar { return "def" } +} + +fun foobar(x: String, y: String, z: String) = x + y + z + +fun box(): String { + val test = foobar("abc", bar2(), "ghi") + return if (test == "abcdefghi") + "OK" + else "Failed, test=$test" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/innerLoopWithStack.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/innerLoopWithStack.kt new file mode 100644 index 00000000000..96cf2e2eaec --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/innerLoopWithStack.kt @@ -0,0 +1,9 @@ +fun box(): String { + var x = "OK" + do { + while (true) { + x = x + break + } + } while (false) + return x +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/kt14581.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/kt14581.kt new file mode 100644 index 00000000000..0010f1ffdbd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/kt14581.kt @@ -0,0 +1,11 @@ +fun foo(x: String): String { + var y: String + do { + y = x + } while (y != x.bar(x)) + return y +} + +inline fun String.bar(other: String) = this + +fun box(): String = foo("OK") \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/kt9022And.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/kt9022And.kt new file mode 100644 index 00000000000..757b5c940be --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/kt9022And.kt @@ -0,0 +1,9 @@ +fun box(): String { + var cycle = true; + while (true) { + if (true && break) { + return "fail" + } + } + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/kt9022Or.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/kt9022Or.kt new file mode 100644 index 00000000000..3b8a943d781 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/kt9022Or.kt @@ -0,0 +1,9 @@ +fun box(): String { + var cycle = true; + while (true) { + if (true || break) { + return "OK" + } + } + return "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/popSizes.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/popSizes.kt new file mode 100644 index 00000000000..8c736e5952b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/popSizes.kt @@ -0,0 +1,13 @@ +fun foo(x: Long, y: Int, z: Double, s: String) {} + +fun box(): String { + while (true) { + try { + foo(0, 0, 0.0, "" + continue) + } + finally { + foo(0, 0, 0.0, "" + break) + } + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/tryFinally1.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/tryFinally1.kt new file mode 100644 index 00000000000..b918861535a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/tryFinally1.kt @@ -0,0 +1,12 @@ +fun box(): String { + var x = "OK" + while (true) { + try { + x = x + continue + } + finally { + x = x + break + } + } + return x +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/tryFinally2.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/tryFinally2.kt new file mode 100644 index 00000000000..147362a181c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/tryFinally2.kt @@ -0,0 +1,13 @@ +fun box(): String { + var r = "" + for (i in 1..1) { + try { + r += "O" + break + } finally { + r += "K" + continue + } + } + return r +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/whileTrueBreak.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/whileTrueBreak.kt new file mode 100644 index 00000000000..09b73099a16 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/breakContinueInExpressions/whileTrueBreak.kt @@ -0,0 +1,4 @@ +fun box(): String { + while (true) break + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/breakInFinally.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/breakInFinally.kt new file mode 100644 index 00000000000..d761ee60360 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/breakInFinally.kt @@ -0,0 +1,11 @@ +fun box(): String { + while (true) { + try { + continue; + } + finally { + break; + } + } + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/compareBoxedIntegerToZero.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/compareBoxedIntegerToZero.kt new file mode 100644 index 00000000000..6b2091be148 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/compareBoxedIntegerToZero.kt @@ -0,0 +1,8 @@ +fun box(): String { + val x: Int? = 0 + if (x != 0) return "Fail $x" + if (0 != x) return "Fail $x" + if (!(x == 0)) return "Fail $x" + if (!(0 == x)) return "Fail $x" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/conditionOfEmptyIf.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/conditionOfEmptyIf.kt new file mode 100644 index 00000000000..153b73525c7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/conditionOfEmptyIf.kt @@ -0,0 +1,13 @@ +var result = "Fail" + +fun setOK(): Boolean { + result = "OK" + return true +} + +fun box(): String { + if (setOK()) { + } else { + } + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/continueInExpr.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/continueInExpr.kt new file mode 100644 index 00000000000..328f8efafec --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/continueInExpr.kt @@ -0,0 +1,16 @@ +// WITH_RUNTIME + +fun concatNonNulls(strings: List): String { + var result = "" + for (str in strings) { + result += str?:continue + } + return result +} + +fun box(): String { + val test = concatNonNulls(listOf("abc", null, null, "", null, "def")) + if (test != "abcdef") return "Failed: test=$test" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/continueInFor.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/continueInFor.kt new file mode 100644 index 00000000000..7d5bb6a3dc4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/continueInFor.kt @@ -0,0 +1,123 @@ +fun for_int_range(): Int { + var c = 0 + for (i in 1..10) { + if (c >= 5) continue + c++ + } + return c +} + +fun for_byte_range(): Int { + var c = 0 + val from: Byte = 1 + val to: Byte = 10 + for (i in from..to) { + if (c >= 5) continue + c++ + } + return c +} + +fun for_long_range(): Int { + var c = 0 + val from: Long = 1 + val to: Long = 10 + for (i in from..to) { + if (c >= 5) continue + c++ + } + return c +} + +fun for_int_list(): Int { + val a = ArrayList() + a.add(0); a.add(0); a.add(0); a.add(0); a.add(0) + a.add(0); a.add(0); a.add(0); a.add(0); a.add(0) + var c = 0 + for (i in a) { + if (c >= 5) continue + c++ + } + return c +} + +fun for_byte_list(): Int { + val a = ArrayList() + a.add(0); a.add(0); a.add(0); a.add(0); a.add(0) + a.add(0); a.add(0); a.add(0); a.add(0); a.add(0) + var c = 0 + for (i in a) { + if (c >= 5) continue + c++ + } + return c +} + +fun for_long_list(): Int { + val a = ArrayList() + a.add(0); a.add(0); a.add(0); a.add(0); a.add(0) + a.add(0); a.add(0); a.add(0); a.add(0); a.add(0) + var c = 0 + for (i in a) { + if (c >= 5) continue + c++ + } + return c +} + +fun for_double_list(): Int { + val a = ArrayList() + a.add(0.0); a.add(0.0); a.add(0.0); a.add(0.0); a.add(0.0) + a.add(0.0); a.add(0.0); a.add(0.0); a.add(0.0); a.add(0.0) + var c = 0 + for (i in a) { + if (c >= 5) continue + c++ + } + return c +} + +fun for_object_list(): Int { + val a = ArrayList() + a.add(0.0); a.add(0.0); a.add(0.0); a.add(0.0); a.add(0.0) + a.add(0.0); a.add(0.0); a.add(0.0); a.add(0.0); a.add(0.0) + var c = 0 + for (i in a) { + if (c >= 5) continue + c++ + } + return c +} + +fun for_str_array(): Int { + val a = arrayOfNulls(10) + var c = 0 + for (i in a) { + if (c >= 5) continue + c++ + } + return c +} + +fun for_intarray(): Int { + val a = IntArray(10) + var c = 0 + for (i in a) { + if (c >= 5) continue + c++ + } + return c +} + +fun box(): String { + if (for_int_range() != 5) return "fail 1" + if (for_byte_range() != 5) return "fail 2" + if (for_long_range() != 5) return "fail 3" + if (for_intarray() != 5) return "fail 4" + if (for_str_array() != 5) return "fail 5" + if (for_int_list() != 5) return "fail 6" + if (for_byte_list() != 5) return "fail 7" + if (for_long_list() != 5) return "fail 8" + if (for_double_list() != 5) return "fail 9" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/continueInForCondition.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/continueInForCondition.kt new file mode 100644 index 00000000000..3ebace16102 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/continueInForCondition.kt @@ -0,0 +1,12 @@ +// WITH_RUNTIME + +fun foo(): List? = listOf("abcde") + +fun box(): String { + for (i in 1..3) { + for (value in foo() ?: continue) { + if (value != "abcde") return "Fail" + } + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/continueInWhile.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/continueInWhile.kt new file mode 100644 index 00000000000..79b4ea623ff --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/continueInWhile.kt @@ -0,0 +1,16 @@ +fun foo(i: Int): Int { + var count = i; + var result = 0; + while(count > 0) { + count = count - 1; + if (count <= 2) continue; + result = result + count; + } + return result; +} + +fun box(): String { + if (foo(4) != 3) return "Fail 1" + if (foo(5) != 7) return "Fail 2" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/continueToLabelInFor.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/continueToLabelInFor.kt new file mode 100644 index 00000000000..fe644d6e64b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/continueToLabelInFor.kt @@ -0,0 +1,123 @@ +fun for_int_range(): Int { + var c = 0 + loop@ for (i in 1..10) { + if (c >= 5) continue@loop + c++ + } + return c +} + +fun for_byte_range(): Int { + var c = 0 + val from: Byte = 1 + val to: Byte = 10 + loop@ for (i in from..to) { + if (c >= 5) continue@loop + c++ + } + return c +} + +fun for_long_range(): Int { + var c = 0 + val from: Long = 1 + val to: Long = 10 + loop@ for (i in from..to) { + if (c >= 5) continue@loop + c++ + } + return c +} + +fun for_int_list(): Int { + val a = ArrayList() + a.add(0); a.add(0); a.add(0); a.add(0); a.add(0) + a.add(0); a.add(0); a.add(0); a.add(0); a.add(0) + var c = 0 + loop@ for (i in a) { + if (c >= 5) continue@loop + c++ + } + return c +} + +fun for_byte_list(): Int { + val a = ArrayList() + a.add(0); a.add(0); a.add(0); a.add(0); a.add(0) + a.add(0); a.add(0); a.add(0); a.add(0); a.add(0) + var c = 0 + loop@ for (i in a) { + if (c >= 5) continue@loop + c++ + } + return c +} + +fun for_long_list(): Int { + val a = ArrayList() + a.add(0); a.add(0); a.add(0); a.add(0); a.add(0) + a.add(0); a.add(0); a.add(0); a.add(0); a.add(0) + var c = 0 + loop@ for (i in a) { + if (c >= 5) continue@loop + c++ + } + return c +} + +fun for_double_list(): Int { + val a = ArrayList() + a.add(0.0); a.add(0.0); a.add(0.0); a.add(0.0); a.add(0.0) + a.add(0.0); a.add(0.0); a.add(0.0); a.add(0.0); a.add(0.0) + var c = 0 + loop@ for (i in a) { + if (c >= 5) continue@loop + c++ + } + return c +} + +fun for_object_list(): Int { + val a = ArrayList() + a.add(0.0); a.add(0.0); a.add(0.0); a.add(0.0); a.add(0.0) + a.add(0.0); a.add(0.0); a.add(0.0); a.add(0.0); a.add(0.0) + var c = 0 + loop@ for (i in a) { + if (c >= 5) continue@loop + c++ + } + return c +} + +fun for_str_array(): Int { + val a = arrayOfNulls(10) + var c = 0 + loop@ for (i in a) { + if (c >= 5) continue@loop + c++ + } + return c +} + +fun for_intarray(): Int { + val a = IntArray(10) + var c = 0 + loop@ for (i in a) { + if (c >= 5) continue@loop + c++ + } + return c +} + +fun box(): String { + if (for_int_range() != 5) return "fail 1" + if (for_byte_range() != 5) return "fail 2" + if (for_long_range() != 5) return "fail 3" + if (for_intarray() != 5) return "fail 4" + if (for_str_array() != 5) return "fail 5" + if (for_int_list() != 5) return "fail 6" + if (for_byte_list() != 5) return "fail 7" + if (for_long_list() != 5) return "fail 8" + if (for_double_list() != 5) return "fail 9" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/doWhile.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/doWhile.kt new file mode 100644 index 00000000000..f9b776c736c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/doWhile.kt @@ -0,0 +1,15 @@ +fun box(): String { + var x = 0 + do x++ while (x < 5) + if (x != 5) return "Fail 1 $x" + + var y = 0 + do { y++ } while (y < 5) + if (y != 5) return "Fail 2 $y" + + var z = "" + do { z += z.length } while (z.length < 5) + if (z != "01234") return "Fail 3 $z" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/doWhileFib.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/doWhileFib.kt new file mode 100644 index 00000000000..088f74cb660 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/doWhileFib.kt @@ -0,0 +1,12 @@ +fun box(): String { + var fx = 1 + var fy = 1 + + do { + var tmp = fy + fy = fx + fy + fx = tmp + } while (fy < 100) + + return if (fy == 144) "OK" else "Fail $fx $fy" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/doWhileWithContinue.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/doWhileWithContinue.kt new file mode 100644 index 00000000000..bb9c73dc6a8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/doWhileWithContinue.kt @@ -0,0 +1,21 @@ +fun box(): String { + var i = 0 + do { + if (i++ > 100) break; + continue; + } while(false) + if (i != 1) return "Fail 1, expected 1, but $i" + + i = 0 + do { + if (i++ > 100) break; + continue; + } while(i<10) + if (i != 10) return "Fail 2, expected 10, but $i" + + i = 0 + do continue while(i++<10) + if (i != 11) return "Fail 3, expected 11, but $i" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/emptyDoWhile.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/emptyDoWhile.kt new file mode 100644 index 00000000000..0f52a36e3b6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/emptyDoWhile.kt @@ -0,0 +1,9 @@ +fun box(): String { + do while (false); + + var x = 0 + do while (x++<5); + if (x != 6) return "Fail: $x" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/emptyFor.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/emptyFor.kt new file mode 100644 index 00000000000..6a09c1b3b43 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/emptyFor.kt @@ -0,0 +1,19 @@ +var index = 0 + +interface IterableIterator : Iterator { + operator fun iterator(): Iterator = this +} + +val iterator = object : IterableIterator { + override fun hasNext() = index < 5 + override fun next() = index++ +} + +fun box(): String { + for (x in 1..5); + + for (x in iterator); + if (index != 5) return "Fail: $index" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/emptyWhile.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/emptyWhile.kt new file mode 100644 index 00000000000..c52c5124f52 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/emptyWhile.kt @@ -0,0 +1,9 @@ +fun box(): String { + while (false); + + var x = 0 + while (x++<5); + if (x != 6) return "Fail: $x" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/factorialTest.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/factorialTest.kt new file mode 100644 index 00000000000..fdb108f8bdc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/factorialTest.kt @@ -0,0 +1,44 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun facWhile(i: Int): Int { + var count = 1; + var result = 1; + while(count < i) { + count = count + 1; + result = result * count; + } + return result; +} + +fun facBreak(i: Int): Int { + var count = 1; + var result = 1; + while(true) { + count = count + 1; + result = result * count; + if (count == i) break; + } + return result; +} + +fun facDoWhile(i: Int): Int { + var count = 1; + var result = 1; + do { + count = count + 1; + result = result * count; + } while(count != i); + return result; +} + +fun box(): String { + assertEquals(6, facWhile(3)) + assertEquals(6, facBreak(3)) + assertEquals(6, facDoWhile(3)) + assertEquals(120, facWhile(5)) + assertEquals(120, facBreak(5)) + assertEquals(120, facDoWhile(5)) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/finallyOnEmptyReturn.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/finallyOnEmptyReturn.kt new file mode 100644 index 00000000000..db1262a9d7a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/finallyOnEmptyReturn.kt @@ -0,0 +1,14 @@ +var result = "Fail" + +fun foo() { + try { + return + } finally { + result = "OK" + } +} + +fun box(): String { + foo() + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/forArrayList.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/forArrayList.kt new file mode 100644 index 00000000000..cce12773de3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/forArrayList.kt @@ -0,0 +1,11 @@ +// WITH_RUNTIME +val alist = arrayListOf(1, 2, 3) // : j.u.ArrayList + +fun box(): String { + var result = 0 + for (i: Int in alist) { + result += i + } + + return if (result == 6) "OK" else "fail: $result" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/forArrayListMultiDecl.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/forArrayListMultiDecl.kt new file mode 100644 index 00000000000..04bd627762e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/forArrayListMultiDecl.kt @@ -0,0 +1,12 @@ +// WITH_RUNTIME +val alist = arrayListOf(1 to 2, 2 to 3, 3 to 4) + +fun box(): String { + var result = 0 + for ((i: Int, z: Int) in alist) { + + result += i + z + } + + return if (result == 15) "OK" else "fail: $result" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/forInSmartCastToArray.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/forInSmartCastToArray.kt new file mode 100644 index 00000000000..83a919d7e9f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/forInSmartCastToArray.kt @@ -0,0 +1,14 @@ +fun f(x: Any?): Any? { + if (x is Array<*>) { + for (i in x) { + return i + } + } + return "FAIL" +} + +fun box(): String { + val a = arrayOfNulls(1) as Array + a[0] = "OK" + return f(a) as String +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/forIntArray.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/forIntArray.kt new file mode 100644 index 00000000000..9fc295b3eda --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/forIntArray.kt @@ -0,0 +1,14 @@ +fun box() : String { + val a = arrayOfNulls(5) + var i = 0 + var sum = 0 + for(el in 0..4) { + a[i] = i++ + } + for (el in (a as Array)) { + sum = sum + el + } + if(sum != 10) return "a failed" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/forLoopMemberExtensionAll.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/forLoopMemberExtensionAll.kt new file mode 100644 index 00000000000..bd701f507a2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/forLoopMemberExtensionAll.kt @@ -0,0 +1,26 @@ +class It { +} + +class C { +} + +class X { + var hasNext = true + operator fun It.hasNext() = if (hasNext) {hasNext = false; true} else false + operator fun It.next() = 5 + operator fun C.iterator(): It = It() + + fun test() { + for (i in C()) { + foo(i) + } + } + +} + +fun foo(x: Int) {} + +fun box(): String { + X().test() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/forLoopMemberExtensionHasNext.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/forLoopMemberExtensionHasNext.kt new file mode 100644 index 00000000000..fd0e52ec3f8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/forLoopMemberExtensionHasNext.kt @@ -0,0 +1,26 @@ +class It { + operator fun next() = 5 +} + +class C { + operator fun iterator(): It = It() +} + +class X { + var hasNext = true + operator fun It.hasNext() = if (hasNext) {hasNext = false; true} else false + + fun test() { + for (i in C()) { + foo(i) + } + } + +} + +fun foo(x: Int) {} + +fun box(): String { + X().test() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/forLoopMemberExtensionNext.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/forLoopMemberExtensionNext.kt new file mode 100644 index 00000000000..e5a78d84cde --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/forLoopMemberExtensionNext.kt @@ -0,0 +1,29 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class It { + var hasNext = true + operator fun hasNext() = if (hasNext) {hasNext = false; true} else false +} + +class C { + operator fun iterator(): It = It() +} + +class X { + operator fun It.next() = 5 + + fun test() { + for (i in C()) { + foo(i) + } + } + +} + +fun foo(x: Int) {} + +fun box(): String { + X().test() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/forNullableIntArray.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/forNullableIntArray.kt new file mode 100644 index 00000000000..10e29bcba89 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/forNullableIntArray.kt @@ -0,0 +1,15 @@ +fun box() : String { + val b : Array = arrayOfNulls (5) + var i = 0 + var sum = 0 + while(i < 5) { + b[i] = i++ + } + sum = 0 + for (el in b) { + sum = sum + (el ?: 0) + } + if(sum != 10) return "b failed" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/forPrimitiveIntArray.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/forPrimitiveIntArray.kt new file mode 100644 index 00000000000..566894de73a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/forPrimitiveIntArray.kt @@ -0,0 +1,14 @@ +fun box() : String { + val a = IntArray (5) + var i = 0 + var sum = 0 + for(el in 0..4) { + a[i] = i++ + } + for (el in a) { + sum = sum + el + } + if(sum != 10) return "a failed" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/forUserType.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/forUserType.kt new file mode 100644 index 00000000000..6dfbdbd00d7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/forUserType.kt @@ -0,0 +1,117 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box() : String { + var sum : Int = 0 + var i = 0 + + val c6 = MyCollection4() + sum = 0 + for (el in c6) { + sum = sum + el + } + if(sum != 15) return "c6 failed" + + val c5 = MyCollection3() + sum = 0 + for (el in c5) { + sum = sum + (el ?: 0) + } + if(sum != 15) return "c5 failed" + + val c1: Iterable = MyCollection1() + sum = 0 + for (el in c1) { + sum = sum + el!! + } + if(sum != 15) return "c1 failed" + + val c2 = MyCollection1() + sum = 0 + for (el in c2) { + sum = sum + el!! + } + if(sum != 15) return "c2 failed" + + val c3: Iterable = MyCollection2() + sum = 0 + for (el in c3) { + sum = sum + el!! + } + if(sum != 15) return "c3 failed" + + val c4 = MyCollection2() + sum = 0 + for (el in c4) { + sum = sum + el!! + } + if(sum != 15) return "c4 failed" + + val a : Array = arrayOfNulls(5) as Array + for(el in 0..4) { + a[i] = i++ + } + sum = 0 + for (el in a) { + sum = sum + el!! + } + if(sum != 10) return "a failed" + + val b : Array = arrayOfNulls (5) + i = 0 + while(i < 5) { + b[i] = i++ + } + sum = 0 + for (el in b) { + sum = sum + (el ?: 0) + } + System.out?.println(sum) + if(sum != 10) return "b failed" + + return "OK" +} + +class MyCollection1(): Iterable { + override fun iterator(): Iterator = MyIterator() + + class MyIterator(): Iterator { + var k : Int = 5 + + override fun next() : Int = k-- + override fun hasNext() = k > 0 + } +} + +class MyCollection2(): Iterable { + override fun iterator(): Iterator = MyIterator() + + class MyIterator(): Iterator { + var k : Int = 5 + + override fun next() : Int = k-- + override fun hasNext() : Boolean = k > 0 + } +} + +class MyCollection3() { + operator fun iterator() = MyIterator() + + class MyIterator() { + var k : Int = 5 + + operator fun next() : Int? = k-- + operator fun hasNext() : Boolean = k > 0 + } +} + +class MyCollection4() { + operator fun iterator() = MyIterator() + + class MyIterator() { + var k : Int = 5 + + operator fun next() : Int = k-- + operator fun hasNext() = k > 0 + } +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/inRangeConditionsInWhen.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/inRangeConditionsInWhen.kt new file mode 100644 index 00000000000..09f2faa5557 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/inRangeConditionsInWhen.kt @@ -0,0 +1,8 @@ +operator fun Int.contains(i : Int) = true + +fun box(): String { + when (1) { + in 2 -> return "OK" + else -> return "fail" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt12908.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt12908.kt new file mode 100644 index 00000000000..e35d92b93dc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt12908.kt @@ -0,0 +1,20 @@ +var field: Int = 0 + +fun next(): Int { + return ++field +} + + +fun box(): String { + val task: String + + do { + if (next() % 2 == 0) { + task = "OK" + break + } + } + while (true) + + return task +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt12908_2.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt12908_2.kt new file mode 100644 index 00000000000..f4fd0e0555e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt12908_2.kt @@ -0,0 +1,20 @@ +var field: Int = 0 + +fun next(): Int { + return ++field +} + + +fun box(): String { + val task: String + + do { + if (next() % 2 == 0) { + task = "OK" + break + } + } + while (!false) + + return task +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt1441.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt1441.kt new file mode 100644 index 00000000000..7e5099064b0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt1441.kt @@ -0,0 +1,16 @@ +class Foo { + var rnd = 10 + + public override fun equals(that : Any?) : Boolean = that is Foo && (that.rnd == rnd) +} + +fun box() : String { + val a = Foo() + val b = Foo() + if (a !== a) return "fail 1" + if (b !== b) return "fail 2" + if (b === a) return "fail 3" + if (a === b) return "fail 4" + if( a !=b ) return "fail5" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt14839.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt14839.kt new file mode 100644 index 00000000000..c76925da31f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt14839.kt @@ -0,0 +1,10 @@ +fun box(): String { + try { + } catch (e: Exception) { + inlineFunctionWithDefaultArguments(e) + } + return "OK" +} + +inline fun inlineFunctionWithDefaultArguments(t: Throwable? = null, bug: Boolean = true) = + Unit \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt1688.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt1688.kt new file mode 100644 index 00000000000..0bbc232c5f1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt1688.kt @@ -0,0 +1,10 @@ +fun box(): String { + var s = "" + try { + throw RuntimeException() + } catch (e : RuntimeException) { + } finally { + s += "OK" + } + return s +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt1742.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt1742.kt new file mode 100644 index 00000000000..6e950e30e41 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt1742.kt @@ -0,0 +1,7 @@ +fun box(): String { + val x = 2 + return when(x) { + in (1..3) -> "OK" + else -> "fail" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt1899.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt1899.kt new file mode 100644 index 00000000000..92a38e1bd89 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt1899.kt @@ -0,0 +1,5 @@ +fun box(): String { + if (1 != 0) { + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt2147.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt2147.kt new file mode 100644 index 00000000000..df664fb16ef --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt2147.kt @@ -0,0 +1,9 @@ +class Foo { + fun isOk() = true +} + +fun box(): String { + val foo: Foo? = Foo() + if (foo?.isOk()!!) return "OK" + return "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt2259.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt2259.kt new file mode 100644 index 00000000000..7b695efee06 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt2259.kt @@ -0,0 +1,10 @@ +fun main(args: Array) { + try { + } finally { + try { + } catch (e: Throwable) { + } + } +} + +fun box() = "OK" diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt2291.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt2291.kt new file mode 100644 index 00000000000..a1afcfe91b6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt2291.kt @@ -0,0 +1,6 @@ +fun box(): String { + 1 in 1.rangeTo(10) + 1..10 + 'h' in 'A'.rangeTo('Z') + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt237.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt237.kt new file mode 100644 index 00000000000..dbf2075ffe8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt237.kt @@ -0,0 +1,44 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun main(args: Array?) { + val y: Unit = Unit //do not compile + A() //do not compile + C(Unit) //do not compile + //do not compile + System.out?.println(fff(Unit)) //do not compile + System.out?.println(id(y)) //do not compile + System.out?.println(fff(id(y)) == id(foreach(arrayOfNulls(0) as Array,{ e : Int -> }))) //do not compile +} +class A() + +class C(val value: T) { + fun foo(): T = value +} + +fun fff(x: T) : T { return x } + +fun id(value: T): T = value + +fun foreach(array: Array, action: (Int)-> Unit) { + for (el in array) { + action(el) //exception through compilation (see below) + } +} + +fun almostFilter(array: Array, action: (Int)-> Int) { + for (el in array) { + action(el) + } +} + +fun box() : String { + val a = arrayOfNulls(3) as Array + a[0] = 0 + a[1] = 1 + a[2] = 2 + foreach(a, { el : Int -> System.out?.println(el) }) + almostFilter(a, { el : Int -> el }) + main(null) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt2416.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt2416.kt new file mode 100644 index 00000000000..f1442680ff5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt2416.kt @@ -0,0 +1,16 @@ +fun box(): String { + 9 in 0..9 + val intRange = 0..9 + 9 in intRange + val charRange = '0'..'9' + '9' in charRange + val byteRange = 0.toByte()..9.toByte() + // seems no stdlib available here, thus no contains as extension + 9 in byteRange + val longRange = 0.toLong()..9.toLong() + 9.toLong() in longRange + val shortRange = 0.toShort()..9.toShort() + 9 in shortRange + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt2423.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt2423.kt new file mode 100644 index 00000000000..c6390b86d3c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt2423.kt @@ -0,0 +1,53 @@ +// TARGET_BACKEND: JVM + +// WITH_RUNTIME +// FULL_JDK + +import java.util.LinkedList + +fun ok1(): Boolean { + val queue = LinkedList(listOf(1, 2, 3)) + while (!queue.isEmpty()) { + queue.poll() + for (y in 1..3) { + if (queue.contains(y)) { + return true + } + } + } + return false +} + +fun ok2(): Boolean { + val queue = LinkedList(listOf(1, 2, 3)) + val array = arrayOf(1, 2, 3) + while (!queue.isEmpty()) { + queue.poll() + for (y in array) { + if (queue.contains(y)) { + return true + } + } + } + return false +} + +fun ok3(): Boolean { + val queue = LinkedList(listOf(1, 2, 3)) + while (!queue.isEmpty()) { + queue.poll() + var x = 0 + do { + x++ + if (x == 2) return true + } while (x < 2) + } + return false +} + +fun box(): String { + if (!ok1()) return "Fail #1" + if (!ok2()) return "Fail #2" + if (!ok3()) return "Fail #3" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt2577.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt2577.kt new file mode 100644 index 00000000000..c11ba235411 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt2577.kt @@ -0,0 +1,12 @@ +fun foo(): Int { + try { + } finally { + try { + return 1 + } catch (e: Throwable) { + return 2 + } + } +} + +fun box() = if (foo() == 1) "OK" else "Fail" diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt2597.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt2597.kt new file mode 100644 index 00000000000..af5af144a86 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt2597.kt @@ -0,0 +1,10 @@ +fun box(): String { + var i = 0 + { + if (1 == 1) { + i++ + } else { + } + }() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt299.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt299.kt new file mode 100644 index 00000000000..9cb4628e7da --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt299.kt @@ -0,0 +1,21 @@ +class MyRange1() : ClosedRange { + override val start: Int + get() = 0 + override val endInclusive: Int + get() = 0 + override fun contains(item: Int) = true +} + +class MyRange2() { + operator fun contains(item: Int) = true +} + +fun box(): String { + if (1 in MyRange1()) { + if (1 in MyRange2()) { + return "OK" + } + return "fail 2" + } + return "fail 1" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt3087.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt3087.kt new file mode 100644 index 00000000000..5858faa4364 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt3087.kt @@ -0,0 +1,26 @@ +fun putNumberCompareAsUnit() { + if (1 == 1) { + } + else if (1 == 1) { + } +} + +fun putNumberCompareAsVoid() { + if (1 == 1) { + 1 == 1 + } else { + } +} + +fun putInvertAsUnit(b: Boolean) { + if (1 == 1) { + } else if (!b) { + } +} + +fun box(): String { + putNumberCompareAsUnit() + putNumberCompareAsVoid() + putInvertAsUnit(true) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt3203_1.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt3203_1.kt new file mode 100644 index 00000000000..a1b72471df1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt3203_1.kt @@ -0,0 +1,19 @@ +fun testIf() { + val condition = true + val result = if (condition) { + val hello: String? = "hello" + if (hello == null) { + false + } + else { + true + } + } + else true + if (!result) throw AssertionError("result is false") +} + +fun box(): String { + testIf() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt3203_2.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt3203_2.kt new file mode 100644 index 00000000000..bde4cc3fe77 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt3203_2.kt @@ -0,0 +1,20 @@ +fun check1() { + val result = if (true) { + if (true) 1 else 2 + } + else 3 + if (result != 1) throw AssertionError("result: $result") +} + +fun check2() { + val result = if (true) + if (true) 1 else 2 + else 3 + if (result != 1) throw AssertionError("result: $result") +} + +fun box(): String { + check1() + check2() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt3273.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt3273.kt new file mode 100644 index 00000000000..187dc50ecf8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt3273.kt @@ -0,0 +1,21 @@ +fun printlnMock(a: Any) {} + +public fun testCoalesce() { + val value: String = when { + true -> { + if (true) { + "foo" + } else { + "bar" + } + } + else -> "Hello world" + } + + printlnMock(value.length) +} + +fun box(): String { + testCoalesce() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt3280.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt3280.kt new file mode 100644 index 00000000000..2a2b87a8f1c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt3280.kt @@ -0,0 +1,24 @@ +fun foo() { + var x = 0 + do { + x++ + var y = x + 5 + } while (y < 10) + if (x != 5) throw AssertionError("$x") +} + +fun bar() { + var b = false + do { + var x = "X" + var y = "Y" + b = true + } while (x + y != "XY") + if (!b) throw AssertionError() +} + +fun box(): String { + foo() + bar() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt3574.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt3574.kt new file mode 100644 index 00000000000..3b2fb00695b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt3574.kt @@ -0,0 +1,12 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun nil() = null + +fun list() = java.util.Arrays.asList("1") + +fun box(): String { + for (x in nil()?:list()) { + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt416.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt416.kt new file mode 100644 index 00000000000..85876312256 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt416.kt @@ -0,0 +1,4 @@ +fun box() : String { + var a = 10 + return if(a?.plus(10) == 20) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt513.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt513.kt new file mode 100644 index 00000000000..74092c47aed --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt513.kt @@ -0,0 +1,24 @@ +// WITH_RUNTIME + +class A() { + infix fun ArrayList.add3(el: T) = add(el) + + fun test(list: ArrayList) { + for (i in 1..10) { + list add3 i + } + } +} + +infix fun ArrayList.add2(el: T) = add(el) + +fun box() : String{ + var list = ArrayList() + for (i in 1..10) { + list.add(i) + list add2 i + } + A().test(list) + println(list) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt628.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt628.kt new file mode 100644 index 00000000000..234e336e5a7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt628.kt @@ -0,0 +1,48 @@ +class A() { + fun action() = "OK" + + infix fun infix(a: String) = "O" + a + + val property = "OK" + + val a : A + get() = A() +} + +fun test1() = A()!!.property +fun test2() = (A() as A?)!!.property +fun test3() = A()!!.action() +fun test4() = (A() as A?)!!.action() +fun test5() = (null as A?)!!.action() +fun test6() = A().a.a!!.action() +fun test7() = 10!!.plus(11) +fun test8() = (10 as Int?)!!.plus(11) +fun test9() = A()!! infix "K" +fun test10() = (A() as A?) !! infix "K" +fun test11() = (A() as A?) !! infix("K") +fun test12() = A()!! infix ("K") + +fun box() : String { + if(test1() != "OK") return "fail" + if(test2() != "OK") return "fail" + if(test3() != "OK") return "fail" + if(test4() != "OK") return "fail" + + try { + test5() + return "fail" + } + catch(e: NullPointerException) { // + } + + if(test6() != "OK") return "fail" + if(test7() != 21) return "fail" + if(test8() != 21) return "fail" + + if(test9() != "OK") return "fail" + if(test10() != "OK") return "fail" + if(test11() != "OK") return "fail" + if(test12() != "OK") return "fail" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt769.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt769.kt new file mode 100644 index 00000000000..af1d3682358 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt769.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +package w_range + +fun box() : String { + var i = 0 + when (i) { + 1 -> i-- + else -> { i = 2 } + } + System.out?.println(i) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt772.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt772.kt new file mode 100644 index 00000000000..6facb9ef23d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt772.kt @@ -0,0 +1,25 @@ +package demo2 + +fun print(o : Any?) {} + +fun test(i : Int) { + var monthString : String? = "" + when (i) { + 1 -> { + print(1) + print(2) + print(3) + print(4) + print(5) + } + else -> { + monthString = "Invalid month" + } + } + print(monthString) +} + +fun box() : String { + for (i in 1..12) test(i) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt773.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt773.kt new file mode 100644 index 00000000000..6facb9ef23d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt773.kt @@ -0,0 +1,25 @@ +package demo2 + +fun print(o : Any?) {} + +fun test(i : Int) { + var monthString : String? = "" + when (i) { + 1 -> { + print(1) + print(2) + print(3) + print(4) + print(5) + } + else -> { + monthString = "Invalid month" + } + } + print(monthString) +} + +fun box() : String { + for (i in 1..12) test(i) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt8148.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt8148.kt new file mode 100644 index 00000000000..39a1846ee54 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt8148.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class A(var value: String) + +fun box(): String { + val a = A("start") + + try { + test(a) + } catch(e: java.lang.RuntimeException) { + + } + + if (a.value != "start, try, finally1, finally2") return "fail: ${a.value}" + + return "OK" +} + +fun test(a: A) : String { + try { + try { + a.value += ", try" + return a.value + } finally { + a.value += ", finally1" + } + } finally { + a.value += ", finally2" + throw RuntimeException("fail") + } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt8148_break.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt8148_break.kt new file mode 100644 index 00000000000..916af6bc06c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt8148_break.kt @@ -0,0 +1,36 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class A(var value: String) + +fun box(): String { + val a = A("start") + + try { + test(a) + } catch(e: java.lang.RuntimeException) { + + } + + if (a.value != "start, try, finally1, finally2") return "fail: ${a.value}" + + return "OK" +} + +fun test(a: A) : String { + while (true) { + try { + try { + a.value += ", try" + break + } + finally { + a.value += ", finally1" + } + } + finally { + a.value += ", finally2" + throw RuntimeException("fail") + } + } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt8148_continue.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt8148_continue.kt new file mode 100644 index 00000000000..2cf60fb734e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt8148_continue.kt @@ -0,0 +1,37 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class A(var value: String) + +fun box(): String { + val a = A("start") + + try { + test(a) + } catch(e: java.lang.RuntimeException) { + + } + + if (a.value != "start, try, finally1, finally2") return "fail: ${a.value}" + + return "OK" +} + +fun test(a: A) : String { + while (a.value == "start") { + try { + try { + a.value += ", try" + continue + } + finally { + a.value += ", finally1" + } + } + finally { + a.value += ", finally2" + throw RuntimeException("fail") + } + } + return "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt870.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt870.kt new file mode 100644 index 00000000000..9dde0366a40 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt870.kt @@ -0,0 +1,5 @@ +fun box() = when { + 1 > 2 -> "false" + 1 >= 1 -> "OK" + else -> "else" + } diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt9022Return.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt9022Return.kt new file mode 100644 index 00000000000..66ccf4bdadf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt9022Return.kt @@ -0,0 +1,29 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun testOr(b: Boolean): Boolean { + return b || return !b; +} + +fun testOr(): Boolean { + return true || return false; +} + + +fun testAnd(b: Boolean): Boolean { + return b && return !b; +} + +fun testAnd(): Boolean { + return true && return false; +} + +fun box(): String { + if (testOr(false) != true) return "fail 1" + if (testOr(true) != true) return "fail 2" + if (testAnd(false) != false) return "fail 3" + if (testAnd(true) != false) return "fail 4" + if (testOr() != true) return "fail 5" + if (testAnd() != false) return "fail 6" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt9022Throw.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt9022Throw.kt new file mode 100644 index 00000000000..adb3fab9356 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt9022Throw.kt @@ -0,0 +1,12 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + var cycle = true; + while (true) { + if (true || throw java.lang.RuntimeException()) { + return "OK" + } + } + return "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt910.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt910.kt new file mode 100644 index 00000000000..a9226bbdba2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt910.kt @@ -0,0 +1,21 @@ +fun foo() : Int = + try { + 2 + } + finally { + "s" + } + +fun bar(set : MutableSet) : Set = + try { + set + } + finally { + set.add(42) + } + +fun box() : String { + if (foo() != 2) return "fail 1" + val s = bar(HashSet()) + return if (s.contains(42)) "OK" else "fail 2" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/kt958.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/kt958.kt new file mode 100644 index 00000000000..f32079bfb69 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/kt958.kt @@ -0,0 +1,3 @@ +fun test() = 239 + +fun box() = if(test() in 239..240) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/longRange.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/longRange.kt new file mode 100644 index 00000000000..b1ab17ee093 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/longRange.kt @@ -0,0 +1,8 @@ +fun box(): String { + val r = 1.toLong()..2 + var s = "" + for (l in r) { + s += l + } + return if (s == "12") "OK" else "fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/quicksort.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/quicksort.kt new file mode 100644 index 00000000000..381a8cf44bb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/quicksort.kt @@ -0,0 +1,41 @@ +fun IntArray.swap(i:Int, j:Int) { + val temp = this[i] + this[i] = this[j] + this[j] = temp +} + +fun IntArray.quicksort() = quicksort(0, size-1) + +fun IntArray.quicksort(L: Int, R:Int) { + val m = this[(L + R) / 2] + var i = L + var j = R + while (i <= j) { + while (this[i] < m) + i++ + while (this[j] > m) + j-- + if (i <= j) { + swap(i++, j--) + } + else { + } + } + if (L < j) + quicksort(L, j) + if (R > i) + quicksort(i, R) +} + +fun box() : String { + val a = IntArray(10) + for(i in 0..4) { + a[2*i] = 2*i + a[2*i+1] = -2*i-1 + } + a.quicksort() + for(i in 0..a.size-2) { + if (a[i] > a[i+1]) return "Fail $i: ${a[i]} > ${a[i+1]}" + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/returnsNothing/ifElse.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/returnsNothing/ifElse.kt new file mode 100644 index 00000000000..98d5401d12e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/returnsNothing/ifElse.kt @@ -0,0 +1,14 @@ +var flag = true + +fun exit(): Nothing = null!! + +fun box(): String { + val a: String + if (flag) { + a = "OK" + } + else { + exit() + } + return a +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/returnsNothing/inlineMethod.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/returnsNothing/inlineMethod.kt new file mode 100644 index 00000000000..5ec5f8feff2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/returnsNothing/inlineMethod.kt @@ -0,0 +1,12 @@ +inline fun exit(): Nothing = null!! + +fun box(): String { + val a: String + try { + a = "OK" + } + catch (e: Exception) { + exit() + } + return a +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/returnsNothing/propertyGetter.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/returnsNothing/propertyGetter.kt new file mode 100644 index 00000000000..1b69f5b1b66 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/returnsNothing/propertyGetter.kt @@ -0,0 +1,16 @@ +var flag = true + +object Test { + val magic: Nothing get() = null!! +} + +fun box(): String { + val a: String + if (flag) { + a = "OK" + } + else { + Test.magic + } + return a +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/returnsNothing/tryCatch.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/returnsNothing/tryCatch.kt new file mode 100644 index 00000000000..bc23f5cb748 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/returnsNothing/tryCatch.kt @@ -0,0 +1,12 @@ +fun exit(): Nothing = null!! + +fun box(): String { + val a: String + try { + a = "OK" + } + catch (e: Exception) { + exit() + } + return a +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/returnsNothing/when.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/returnsNothing/when.kt new file mode 100644 index 00000000000..e4953bb6e3c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/returnsNothing/when.kt @@ -0,0 +1,14 @@ +fun exit(): Nothing = null!! + +var x = 0 + +fun box(): String { + val a: String + when (x) { + 0 -> a = "OK" + 1 -> a = "???" + 2 -> exit() + else -> exit() + } + return a +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchFinallyChain.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchFinallyChain.kt new file mode 100644 index 00000000000..b0ee1f314dc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchFinallyChain.kt @@ -0,0 +1,19 @@ +fun box() : String { + try { + } finally { + try { + try { + } finally { + try { + } finally { + } + } + } catch (e: Exception) { + try { + } catch (f: Exception) { + } finally { + } + } + return "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/catch.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/catch.kt new file mode 100644 index 00000000000..cb00faf1fe3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/catch.kt @@ -0,0 +1,2 @@ +fun box(): String = + "O" + try { throw Exception("oops!") } catch (e: Exception) { "K" } \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/complexChain.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/complexChain.kt new file mode 100644 index 00000000000..36f2e84f29f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/complexChain.kt @@ -0,0 +1,52 @@ +fun cleanup() {} + +inline fun concat(x: String, y: String): String = x + y + +inline fun throws() { + try { + throw Exception() + } + finally { + cleanup() + } +} + +inline fun first(x: String, y: String): String = x + +fun box(): String = + "" + concat( + try { "" } finally { "0" }, + "" + concat( + first( + try { + try { + "O" + } + finally { + "1" + } + } + catch (e: Exception) { + throw e + } + finally { + cleanup() + }, + "2" + ), + first( + try { + throws() + throw Exception() + "3" + } + catch (e: Exception) { + "K" + } + finally { + cleanup() + }, + "4" + ) + ) + ) diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/deadTryCatch.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/deadTryCatch.kt new file mode 100644 index 00000000000..41a91a17e08 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/deadTryCatch.kt @@ -0,0 +1,26 @@ +inline fun catchAll(x: String, block: () -> Unit): String { + try { + block() + } catch (e: Throwable) { + } + return x +} + +inline fun tryTwice(block: () -> Unit) { + try { + block() + try { + block() + } catch (e: Exception) { + } + } catch (e: Exception) { + } +} + +fun box(): String { + return catchAll("OK") { + tryTwice { + throw Exception() + } + } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/differentTypes.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/differentTypes.kt new file mode 100644 index 00000000000..99d56fa995f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/differentTypes.kt @@ -0,0 +1,11 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun foo(b: Byte, s: String, i: Int, d: Double, li: Long): String = "$b $s $i $d $li" + +fun box(): String { + val test = foo(1, "abc", 1, 1.0, try { 1L } catch (e: Exception) { 10L }) + if (test != "1 abc 1 1.0 1") return "Failed, test==$test" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/expectException.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/expectException.kt new file mode 100644 index 00000000000..63bd4900c12 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/expectException.kt @@ -0,0 +1,35 @@ +public inline fun fails(block: () -> Unit): Throwable? { + var thrown: Throwable? = null + try { + block() + } catch (e: Throwable) { + thrown = e + } + if (thrown == null) + throw Exception("Expected an exception to be thrown") + return thrown +} + +public inline fun throwIt(msg: String) { + throw Exception(msg) +} + +fun box(): String { + fails { + throwIt("oops!") + } + + var x = 0 + try { + fails { + x = 1 + } + } + catch (e: Exception) { + x = 2 + } + + if (x != 2) return "Failed: x==$x" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/finally.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/finally.kt new file mode 100644 index 00000000000..2d4b9f825a7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/finally.kt @@ -0,0 +1,2 @@ +fun box(): String = + "O" + try { "K" } finally { "hmmm" } \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/inlineTryCatch.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/inlineTryCatch.kt new file mode 100644 index 00000000000..dd3a181348a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/inlineTryCatch.kt @@ -0,0 +1,17 @@ +inline fun tryOrElse(f1: () -> T, f2: () -> T): T { + try { + return f1() + } + catch (e: Exception) { + return f2() + } +} + +fun testIt() = "abc" + tryOrElse({ "def" }, { "oops" }) + "ghi" + +fun box(): String { + val test = testIt() + if (test != "abcdefghi") return "Failed, test==$test" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/inlineTryExpr.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/inlineTryExpr.kt new file mode 100644 index 00000000000..8205200452a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/inlineTryExpr.kt @@ -0,0 +1,14 @@ +inline fun tryOrElse(f1: () -> T, f2: () -> T): T = + try { f1() } catch (e: Exception) { f2() } + +fun testIt() = + "abc" + + tryOrElse({ try { "def" } catch(e: Exception) { "oops!" } }, { "hmmm..." }) + + "ghi" + +fun box(): String { + val test = testIt() + if (test != "abcdefghi") return "Failed, test==$test" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/inlineTryFinally.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/inlineTryFinally.kt new file mode 100644 index 00000000000..eb488beb689 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/inlineTryFinally.kt @@ -0,0 +1,22 @@ +inline fun tryAndThen(f1: () -> Unit, f2: () -> Unit, f3: () -> T): T { + try { + f1() + } + catch (e: Exception) { + f2() + } + finally { + return f3() + } +} + +fun testIt() = "abc" + + tryAndThen({}, {}, { "def" }) + + "ghi" + +fun box(): String { + val test = testIt() + if (test != "abcdefghi") return "Failed, test==$test" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/kt8608.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/kt8608.kt new file mode 100644 index 00000000000..1d0b92b2c09 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/kt8608.kt @@ -0,0 +1,30 @@ +interface Callable { + fun call(b: Boolean) +} + +inline fun run(f: () -> Unit) { f() } + +class A { + fun foo(): String { + run { + val x = object : Callable { + override fun call(b: Boolean) { + if (b) { + x() + } else { + try { + x() + } catch(t: Throwable) { + } + } + } + } + } + return "OK" + } + + private fun x() {} +} + +fun box(): String = + A().foo() \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/kt9644try.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/kt9644try.kt new file mode 100644 index 00000000000..63921992a06 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/kt9644try.kt @@ -0,0 +1,21 @@ +inline fun doCall(f: () -> Any) = f() + +fun test1() { + val localResult = doCall { + try { "1" } catch (e: Exception) { "2" } + return + } +} + +fun test2(): String { + val localResult = doCall { + try { "1" } catch (e: Exception) { "2" } + return@test2 "OK" + } + return "Hmmm..." +} + +fun box(): String { + test1() + return test2() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/multipleCatchBlocks.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/multipleCatchBlocks.kt new file mode 100644 index 00000000000..4d1bf16a733 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/multipleCatchBlocks.kt @@ -0,0 +1,20 @@ +class Exception1(msg: String): Exception(msg) +class Exception2(msg: String): Exception(msg) +class Exception3(msg: String): Exception(msg) + +fun box(): String = + "O" + try { + throw Exception3("K") + } + catch (e1: Exception1) { + "e1" + } + catch (e2: Exception2) { + "e2" + } + catch (e3: Exception3) { + e3.message + } + catch (e: Exception) { + "e" + } diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/splitTry.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/splitTry.kt new file mode 100644 index 00000000000..c60bde586a1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/splitTry.kt @@ -0,0 +1,25 @@ +inline fun test(s: () -> Int): Int = + try { + val i = s() + i + 10 + } + finally { + 0 + } + +fun box() : String { + test { + try { + val p = 1 + return "OK" + } + catch(e: Exception) { + -2 + } + finally { + -3 + } + } + + return "Failed" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/splitTryCorner1.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/splitTryCorner1.kt new file mode 100644 index 00000000000..bbf5ad07064 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/splitTryCorner1.kt @@ -0,0 +1,11 @@ +fun shouldReturnFalse() : Boolean { + try { + return true + } finally { + if (true) + return false + } +} + +fun box(): String = + if (shouldReturnFalse()) "Failed" else "OK" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/splitTryCorner2.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/splitTryCorner2.kt new file mode 100644 index 00000000000..7c0c3e81c55 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/splitTryCorner2.kt @@ -0,0 +1,22 @@ +fun shouldReturn11() : Int { + var x = 0 + while (true) { + try { + if(x < 10) + x++ + else + break + } + finally { + x++ + } + } + return x +} + +fun box(): String { + val test = shouldReturn11() + if (test != 11) return "Failed, test=$test" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/try.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/try.kt new file mode 100644 index 00000000000..695e324988e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/try.kt @@ -0,0 +1,2 @@ +fun box(): String = + "O" + try { "K" } catch (e: Exception) { "oops!" } \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/tryAfterTry.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/tryAfterTry.kt new file mode 100644 index 00000000000..7d6dcc3d2a3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/tryAfterTry.kt @@ -0,0 +1,4 @@ +fun box(): String = + "" + + try { "O" } catch (e: Exception) { "1" } + + try { throw Exception("oops!") } catch (e: Exception) { "K" } \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/tryAndBreak.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/tryAndBreak.kt new file mode 100644 index 00000000000..a1f867b1c3d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/tryAndBreak.kt @@ -0,0 +1,19 @@ +fun idiv(a: Int, b: Int): Int = + if (b == 0) throw Exception("Division by zero") else a / b + +fun foo(): Int { + var sum = 0 + var i = 2 + while (i > -10) { + sum += try { idiv(100, i) } catch (e: Exception) { break } + i-- + } + return sum +} + +fun box(): String { + val test = foo() + if (test != 150) return "Failed, test=$test" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/tryAndContinue.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/tryAndContinue.kt new file mode 100644 index 00000000000..120d463b00c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/tryAndContinue.kt @@ -0,0 +1,17 @@ +fun idiv(a: Int, b: Int): Int = + if (b == 0) throw Exception("Division by zero") else a / b + +fun foo(): Int { + var sum = 0 + for (i in -10 .. 10) { + sum += try { idiv(100, i) } catch (e: Exception) { continue } + } + return sum +} + +fun box(): String { + val test = foo() + if (test != 0) return "Failed, test=$test" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/tryInsideCatch.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/tryInsideCatch.kt new file mode 100644 index 00000000000..09f9857b57c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/tryInsideCatch.kt @@ -0,0 +1,8 @@ +fun box(): String = + "O" + + try { + throw Exception("oops!") + } + catch (e: Exception) { + try { "K" } catch (e: Exception) { "2" } + } \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/tryInsideTry.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/tryInsideTry.kt new file mode 100644 index 00000000000..3d1ccd9e7ae --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/tryInsideTry.kt @@ -0,0 +1,10 @@ +class MyException(message: String): Exception(message) + +fun box(): String = + "O" + + try { + try { throw Exception("oops!") } catch (mye: MyException) { "1" } + } + catch (e: Exception) { + "K" + } \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/unmatchedInlineMarkers.kt b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/unmatchedInlineMarkers.kt new file mode 100644 index 00000000000..015b4137f65 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/controlStructures/tryCatchInExpressions/unmatchedInlineMarkers.kt @@ -0,0 +1,17 @@ +inline fun catchAll(x: String, block: () -> Unit): String { + try { + block() + } catch (e: Throwable) { + } + return x +} + +inline fun throwIt(msg: String) { + throw Exception(msg) +} + +inline fun bar(x: String): String = + x + catchAll("") { throwIt("oops!") } + +fun box(): String = + bar("OK") diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/asyncIterator.kt b/backend.native/tests/external/codegen/blackbox/coroutines/asyncIterator.kt new file mode 100644 index 00000000000..027eeb08845 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/asyncIterator.kt @@ -0,0 +1,121 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +interface AsyncGenerator { + suspend fun yield(value: T) +} + +interface AsyncSequence { + operator fun iterator(): AsyncIterator +} + +interface AsyncIterator { + operator suspend fun hasNext(): Boolean + operator suspend fun next(): T +} + +fun asyncGenerate(block: suspend AsyncGenerator.() -> Unit): AsyncSequence = object : AsyncSequence { + override fun iterator(): AsyncIterator { + val iterator = AsyncGeneratorIterator() + iterator.nextStep = block.createCoroutine(receiver = iterator, completion = iterator) + return iterator + } +} + +class AsyncGeneratorIterator: AsyncIterator, AsyncGenerator, Continuation { + var computedNext = false + var nextValue: T? = null + var nextStep: Continuation? = null + + // if (computesNext) computeContinuation is Continuation + // if (!computesNext) computeContinuation is Continuation + var computesNext = false + var computeContinuation: Continuation<*>? = null + + suspend fun computeHasNext(): Boolean = CoroutineIntrinsics.suspendCoroutineOrReturn { c -> + computesNext = false + computeContinuation = c + nextStep!!.resume(Unit) + CoroutineIntrinsics.SUSPENDED + } + + suspend fun computeNext(): T = CoroutineIntrinsics.suspendCoroutineOrReturn { c -> + computesNext = true + computeContinuation = c + nextStep!!.resume(Unit) + CoroutineIntrinsics.SUSPENDED + } + + @Suppress("UNCHECKED_CAST") + fun resumeIterator(exception: Throwable?) { + if (exception != null) { + done() + computeContinuation!!.resumeWithException(exception) + return + } + if (computesNext) { + computedNext = false + (computeContinuation as Continuation).resume(nextValue as T) + } else { + (computeContinuation as Continuation).resume(nextStep != null) + } + } + + override suspend fun hasNext(): Boolean { + if (!computedNext) return computeHasNext() + return nextStep != null + } + + override suspend fun next(): T { + if (!computedNext) return computeNext() + computedNext = false + return nextValue as T + } + + private fun done() { + computedNext = true + nextStep = null + } + + // Completion continuation implementation + override fun resume(value: Unit) { + done() + resumeIterator(null) + } + + override fun resumeWithException(exception: Throwable) { + done() + resumeIterator(exception) + } + + // Generator implementation + override suspend fun yield(value: T): Unit = CoroutineIntrinsics.suspendCoroutineOrReturn { c -> + computedNext = true + nextValue = value + nextStep = c + resumeIterator(null) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +fun box(): String { + val seq = asyncGenerate { + yield("O") + yield("K") + } + + var res = "" + + builder { + for (i in seq) { + res += i + } + } + + return res +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/await.kt b/backend.native/tests/external/codegen/blackbox/coroutines/await.kt new file mode 100644 index 00000000000..093436eb720 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/await.kt @@ -0,0 +1,115 @@ +// WITH_RUNTIME +// WITH_COROUTINES +// FILE: promise.kt +import kotlin.coroutines.* + +class Promise(private val executor: ((T) -> Unit) -> Unit) { + private var value: Any? = null + private var thenList: MutableList<(T) -> Unit>? = mutableListOf() + + init { + executor { + value = it + for (resolve in thenList!!) { + resolve(it) + } + thenList = null + } + } + + fun then(onFulfilled: (T) -> S): Promise { + return Promise { resolve -> + if (thenList != null) { + thenList!!.add { resolve(onFulfilled(it)) } + } + else { + resolve(onFulfilled(value as T)) + } + } + } +} + +// FILE: queue.kt + +private val queue = mutableListOf<() -> Unit>() + +fun postpone(computation: () -> T): Promise { + return Promise { resolve -> + queue += { + resolve(computation()) + } + } +} + +fun processQueue() { + while (queue.isNotEmpty()) { + queue.removeAt(0)() + } +} + +// FILE: await.kt +import kotlin.coroutines.* + +private var log = "" + +private var inAwait = false + +suspend fun await(value: Promise): S = suspendCoroutine { continuation -> + if (inAwait) { + throw IllegalStateException("Can't call await recursively") + } + inAwait = true + postpone { + value.then { result -> + continuation.resume(result) + } + } + inAwait = false + CoroutineIntrinsics.SUSPENDED +} + +suspend fun awaitAndLog(value: Promise): S { + log += "before await;" + return await(value.then { result -> + log += "after await: $result;" + result + }) +} + +fun async(c: suspend () -> T): Promise { + return Promise { resolve -> + c.startCoroutine(handleResultContinuation(resolve)) + } +} + +fun asyncOperation(resultSupplier: () -> T) = Promise { resolve -> + log += "before async;" + postpone { + val result = resultSupplier() + log += "after async $result;" + resolve(result) + } +} + +fun getLog() = log + +// FILE: main.kt +import kotlin.coroutines.* + +private fun test() = async { + val o = await(asyncOperation { "O" }) + val k = awaitAndLog(asyncOperation { "K" }) + return@async o + k +} + +fun box(): String { + val resultPromise = test() + var result: String? = null + resultPromise.then { result = it } + processQueue() + + if (result != "OK") return "fail1: $result" + if (getLog() != "before async;after async O;before async;before await;after async K;after await: K;") return "fail2: ${getLog()}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/beginWithException.kt b/backend.native/tests/external/codegen/blackbox/coroutines/beginWithException.kt new file mode 100644 index 00000000000..bcc6ec8b478 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/beginWithException.kt @@ -0,0 +1,36 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +suspend fun suspendHere(): Any = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> } + +fun builder(c: suspend () -> Unit) { + var exception: Throwable? = null + + c.createCoroutine(object : Continuation { + override fun resume(data: Unit) { + } + + override fun resumeWithException(e: Throwable) { + exception = e + } + }).resumeWithException(RuntimeException("OK")) + + if (exception?.message != "OK") { + throw RuntimeException("Unexpected result: ${exception?.message}") + } +} + +fun box(): String { + var result = "OK" + builder { + suspendHere() + result = "fail 1" + } + + builder { + result = "fail 2" + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/beginWithExceptionNoHandleException.kt b/backend.native/tests/external/codegen/blackbox/coroutines/beginWithExceptionNoHandleException.kt new file mode 100644 index 00000000000..fc1142ec9a5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/beginWithExceptionNoHandleException.kt @@ -0,0 +1,32 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* +suspend fun suspendHere(): Any = CoroutineIntrinsics.suspendCoroutineOrReturn { x ->} + +fun builder(c: suspend () -> Unit) { + try { + c.createCoroutine(EmptyContinuation).resumeWithException(RuntimeException("OK")) + } + catch(e: Exception) { + if (e?.message != "OK") { + throw RuntimeException("Unexpected result: ${e?.message}") + } + return + } + + throw RuntimeException("Exception must be thrown above") +} + +fun box(): String { + var result = "OK" + builder { + suspendHere() + result = "fail 1" + } + + builder { + result = "fail 2" + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/coercionToUnit.kt b/backend.native/tests/external/codegen/blackbox/coroutines/coercionToUnit.kt new file mode 100644 index 00000000000..ac01525766c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/coercionToUnit.kt @@ -0,0 +1,47 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + + +suspend fun await(t: T): T = CoroutineIntrinsics.suspendCoroutineOrReturn { c -> + c.resume(t) + CoroutineIntrinsics.SUSPENDED +} + +fun builder(c: suspend () -> Unit): String { + var result = "fail" + c.startCoroutine(handleResultContinuation { + result = "OK" + }) + return result +} + +var TRUE = true +var FALSE = false +fun box(): String { + val r1 = builder { await(Unit) } + if (r1 != "OK") return "fail 1" + + val r2 = builder { + if (await(1) != 1) throw RuntimeException("fail1") + + if (TRUE) return@builder + } + if (r2 != "OK") return "fail 2" + + val r3 = builder { + if (await(1) != 1) throw RuntimeException("fail2") + + if (FALSE) return@builder + } + if (r3 != "OK") return "fail 3" + + val r4 = builder { + if (await(1) != 1) throw RuntimeException("fail3") + + return@builder + } + if (r4 != "OK") return "fail 4" + + return builder { await(1) } +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/breakFinally.kt b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/breakFinally.kt new file mode 100644 index 00000000000..d49e8c0179c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/breakFinally.kt @@ -0,0 +1,55 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + + +class Controller { + var result = "" + + suspend fun suspendWithResult(value: T): T = CoroutineIntrinsics.suspendCoroutineOrReturn { c -> + c.resume(value) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit): String { + val controller = Controller() + c.startCoroutine(controller, EmptyContinuation) + return controller.result +} + +fun box(): String { + val value = builder { + try { + outer@for (x in listOf("A", "B")) { + try { + result += suspendWithResult(x) + for (y in listOf("C", "D")) { + try { + result += suspendWithResult(y) + if (y == "D") { + break@outer + } + } + finally { + result += "!" + } + result += "E" + } + } + finally { + result += "@" + } + result += "ignore" + } + result += "*" + } + finally { + result += "finally" + } + result += "." + } + if (value != "AC!ED!@*finally.") return "fail: $value" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/breakStatement.kt b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/breakStatement.kt new file mode 100644 index 00000000000..8aff6f5a2ff --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/breakStatement.kt @@ -0,0 +1,51 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + + +class Controller { + var result = "" + + suspend fun suspendWithResult(value: T): T = CoroutineIntrinsics.suspendCoroutineOrReturn { c -> + c.resume(value) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit): String { + val controller = Controller() + c.startCoroutine(controller, EmptyContinuation) + return controller.result +} + +fun box(): String { + var value = builder { + outer@for (x in listOf("O", "K")) { + result += suspendWithResult(x) + for (y in listOf("Q", "W")) { + result += suspendWithResult(y) + if (y == "W") { + break@outer + } + } + } + result += "." + } + if (value != "OQW.") return "fail: break outer loop: $value" + + value = builder { + for (x in listOf("O", "K")) { + result += suspendWithResult(x) + for (y in listOf("Q", "W")) { + if (y == "W") { + break + } + result += suspendWithResult(y) + } + } + result += "." + } + if (value != "OQKQ.") return "fail: break inner loop: $value" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/doWhileStatement.kt b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/doWhileStatement.kt new file mode 100644 index 00000000000..932fc621dd7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/doWhileStatement.kt @@ -0,0 +1,42 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + + +class Controller { + var result = "" + + suspend fun suspendWithResult(value: T): T = CoroutineIntrinsics.suspendCoroutineOrReturn { c -> + c.resume(value) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit): String { + val controller = Controller() + c.startCoroutine(controller, EmptyContinuation) + return controller.result +} + +fun box(): String { + var value = builder { + var x = 1 + do { + result += x + } while (suspendWithResult(x++) < 3) + result += "." + } + if (value != "123.") return "fail: suspend as do..while condition: $value" + + value = builder { + var x = 1 + do { + result += suspendWithResult(x) + result += ";" + } while (x++ < 3) + result += "." + } + if (value != "1;2;3;.") return "fail: suspend in do..while body: $value" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/forContinue.kt b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/forContinue.kt new file mode 100644 index 00000000000..e1ff99af922 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/forContinue.kt @@ -0,0 +1,32 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + + +class Controller { + var result = "" + + suspend fun suspendWithResult(value: T): T = CoroutineIntrinsics.suspendCoroutineOrReturn { c -> + c.resume(value) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit): String { + val controller = Controller() + c.startCoroutine(controller, EmptyContinuation) + return controller.result +} + +fun box(): String { + val value = builder { + for (x in listOf("O", "$", "K")) { + if (x == "$") continue + result += suspendWithResult(x) + } + result += "." + } + if (value != "OK.") return "fail: suspend in for body: $value" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/forStatement.kt b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/forStatement.kt new file mode 100644 index 00000000000..5de02f0b5f4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/forStatement.kt @@ -0,0 +1,31 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + + +class Controller { + var result = "" + + suspend fun suspendWithResult(value: T): T = CoroutineIntrinsics.suspendCoroutineOrReturn { c -> + c.resume(value) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit): String { + val controller = Controller() + c.startCoroutine(controller, EmptyContinuation) + return controller.result +} + +fun box(): String { + val value = builder { + for (x in listOf("O", "K")) { + result += suspendWithResult(x) + } + result += "." + } + if (value != "OK.") return "fail: suspend in for body: $value" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/ifStatement.kt b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/ifStatement.kt new file mode 100644 index 00000000000..e7816fb694f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/ifStatement.kt @@ -0,0 +1,76 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + + +class Controller { + var result = "" + + suspend fun suspendWithResult(value: T): T = CoroutineIntrinsics.suspendCoroutineOrReturn { c -> + c.resume(value) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit): String { + val controller = Controller() + c.startCoroutine(controller, EmptyContinuation) + return controller.result +} + +fun box(): String { + var value = builder { + if (suspendWithResult(true)) { + result = "OK" + } + } + if (value != "OK") return "fail: suspend as if condition: $value" + + value = builder { + for (x in listOf(true, false)) { + if (x) { + result += suspendWithResult("O") + } + else { + result += "K" + } + } + } + if (value != "OK") return "fail: suspend in then branch: $value" + + value = builder { + for (x in listOf(true, false)) { + if (x) { + result += "O" + } + else { + result += suspendWithResult("K") + } + } + } + if (value != "OK") return "fail: suspend in else branch: $value" + + value = builder { + for (x in listOf(true, false)) { + if (x) { + result += suspendWithResult("O") + } + else { + result += suspendWithResult("K") + } + } + } + if (value != "OK") return "fail: suspend in both branches: $value" + + value = builder { + for (x in listOf(true, false)) { + if (x) { + result += suspendWithResult("O") + } + result += ";" + } + } + if (value != "O;;") return "fail: suspend in then branch without else: $value" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/returnFromFinally.kt b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/returnFromFinally.kt new file mode 100644 index 00000000000..2453c6947b1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/returnFromFinally.kt @@ -0,0 +1,46 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + + +// Does not work in JVM backend, probably due to bug. It's not clear which behaviour is right. +// TODO: fix the bug and enable for JVM backend +// TARGET_BACKEND: JS + +class Controller { + var result = "" + + suspend fun suspendAndLog(value: T): T = CoroutineIntrinsics.suspendCoroutineOrReturn { c -> + result += "suspend($value);" + c.resume(value) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> String): String { + val controller = Controller() + c.startCoroutine(controller, handleResultContinuation { + controller.result += "return($it);" + }) + return controller.result +} + +fun id(value: T) = value + +fun box(): String { + val value = builder { + try { + if (id(23) == 23) { + return@builder suspendAndLog("OK") + } + } + finally { + result += "finally;" + } + result += "afterFinally;" + "shouldNotReach" + } + if (value != "suspend(OK);finally;return(OK);") return "fail: $value" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/switchLikeWhen.kt b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/switchLikeWhen.kt new file mode 100644 index 00000000000..cf386e60c97 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/switchLikeWhen.kt @@ -0,0 +1,35 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + + +class Controller { + var result = "" + + suspend fun suspendWithResult(value: T): T = CoroutineIntrinsics.suspendCoroutineOrReturn { c -> + result += "[" + c.resume(value) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit): String { + val controller = Controller() + c.startCoroutine(controller, EmptyContinuation) + return controller.result +} + +fun box(): String { + var value = builder { + for (v in listOf("A", "B", "C")) { + when (v) { + "A" -> result += "A;" + "B" -> result += suspendWithResult(v) + "]" + else -> result += suspendWithResult(v) + "]!" + } + } + } + if (value != "A;B]C]!") return "fail: suspend as if condition: $value" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/throwFromCatch.kt b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/throwFromCatch.kt new file mode 100644 index 00000000000..ce70aa13d49 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/throwFromCatch.kt @@ -0,0 +1,59 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + + +class Controller { + var result = "" + + suspend fun suspendAndLog(value: T): T = CoroutineIntrinsics.suspendCoroutineOrReturn { c -> + result += "suspend($value);" + c.resume(value) + CoroutineIntrinsics.SUSPENDED + } + + // Tail calls are not allowed to be Nothing typed. See KT-15051 + suspend fun suspendLogAndThrow(exception: Throwable): Any? = CoroutineIntrinsics.suspendCoroutineOrReturn { c -> + result += "throw(${exception.message});" + c.resumeWithException(exception) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit): String { + val controller = Controller() + c.startCoroutine(controller, object : Continuation { + override fun resume(data: Unit) { + + } + + override fun resumeWithException(exception: Throwable) { + controller.result += "caught(${exception.message});" + } + }) + + return controller.result +} + +fun box(): String { + val value = builder { + try { + try { + suspendAndLog("1") + suspendLogAndThrow(RuntimeException("exception")) + } + catch (e: RuntimeException) { + suspendAndLog("caught") + suspendLogAndThrow(RuntimeException("fromCatch")) + } + } finally { + suspendAndLog("finally") + } + suspendAndLog("ignore") + } + if (value != "suspend(1);throw(exception);suspend(caught);throw(fromCatch);suspend(finally);caught(fromCatch);") { + return "fail: $value" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/throwInTryWithHandleResult.kt b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/throwInTryWithHandleResult.kt new file mode 100644 index 00000000000..6fd8bd06afd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/throwInTryWithHandleResult.kt @@ -0,0 +1,43 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + + +class Controller { + var result = "" + + suspend fun suspendAndLog(value: T): T = CoroutineIntrinsics.suspendCoroutineOrReturn { c -> + result += "suspend($value);" + c.resume(value) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit): String { + val controller = Controller() + c.startCoroutine(controller, object : Continuation { + override fun resume(data: Unit) {} + + override fun resumeWithException(exception: Throwable) { + controller.result += "ignoreCaught(${exception.message});" + } + }) + return controller.result +} + +fun box(): String { + val value = builder { + try { + suspendAndLog("before") + throw RuntimeException("foo") + } catch (e: RuntimeException) { + result += "caught(${e.message});" + } + suspendAndLog("after") + } + if (value != "suspend(before);caught(foo);suspend(after);") { + return "fail: $value" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/whileStatement.kt b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/whileStatement.kt new file mode 100644 index 00000000000..bfd9670c2c8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/controlFlow/whileStatement.kt @@ -0,0 +1,42 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + + +class Controller { + var result = "" + + suspend fun suspendWithResult(value: T): T = CoroutineIntrinsics.suspendCoroutineOrReturn { c -> + c.resume(value) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit): String { + val controller = Controller() + c.startCoroutine(controller, EmptyContinuation) + return controller.result +} + +fun box(): String { + var value = builder { + var x = 1 + while (suspendWithResult(x) <= 3) { + result += x++ + } + result += "." + } + if (value != "123.") return "fail: suspend as while condition: $value" + + value = builder { + var x = 1 + while (x <= 3) { + result += suspendWithResult(x++) + result += ";" + } + result += "." + } + if (value != "1;2;3;.") return "fail: suspend in while body: $value" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/controllerAccessFromInnerLambda.kt b/backend.native/tests/external/codegen/blackbox/coroutines/controllerAccessFromInnerLambda.kt new file mode 100644 index 00000000000..d2ce1e4b381 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/controllerAccessFromInnerLambda.kt @@ -0,0 +1,42 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + var result = false + suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume("OK") + CoroutineIntrinsics.SUSPENDED + } + + fun foo() { + result = true + } +} + +fun builder(c: suspend Controller.() -> Unit) { + val controller = Controller() + c.startCoroutine(controller, EmptyContinuation) + if (!controller.result) throw RuntimeException("fail") +} + +fun noinlineRun(block: () -> Unit) { + block() +} + +fun box(): String { + builder { + if (suspendHere() != "OK") { + throw RuntimeException("fail 1") + } + noinlineRun { + foo() + } + + if (suspendHere() != "OK") { + throw RuntimeException("fail 2") + } + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/defaultParametersInSuspend.kt b/backend.native/tests/external/codegen/blackbox/coroutines/defaultParametersInSuspend.kt new file mode 100644 index 00000000000..c6feea4f052 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/defaultParametersInSuspend.kt @@ -0,0 +1,46 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(a: String = "abc", i: Int = 2): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(a + "#" + (i + 1)) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +fun box(): String { + var result = "OK" + + builder { + var a = suspendHere() + if (a != "abc#3") { + result = "fail 1: $a" + throw RuntimeException(result) + } + + a = suspendHere("cde") + if (a != "cde#3") { + result = "fail 2: $a" + throw RuntimeException(result) + } + + a = suspendHere(i = 6) + if (a != "abc#7") { + result = "fail 3: $a" + throw RuntimeException(result) + } + + a = suspendHere("xyz", 9) + if (a != "xyz#10") { + result = "fail 4: $a" + throw RuntimeException(result) + } + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/dispatchResume.kt b/backend.native/tests/external/codegen/blackbox/coroutines/dispatchResume.kt new file mode 100644 index 00000000000..c09f21dec45 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/dispatchResume.kt @@ -0,0 +1,69 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + var log = "" + var resumeIndex = 0 + + suspend fun suspendWithValue(value: T): T = CoroutineIntrinsics.suspendCoroutineOrReturn { continuation -> + log += "suspend($value);" + continuation.resume(value) + CoroutineIntrinsics.SUSPENDED + } + + suspend fun suspendWithException(value: String): Unit = CoroutineIntrinsics.suspendCoroutineOrReturn { continuation -> + log += "error($value);" + continuation.resumeWithException(RuntimeException(value)) + CoroutineIntrinsics.SUSPENDED + } +} + +fun test(c: suspend Controller.() -> Unit): String { + val controller = Controller() + c.startCoroutine(controller, EmptyContinuation, object: ContinuationDispatcher { + private fun dispatchResume(block: () -> Unit) { + val id = controller.resumeIndex++ + controller.log += "before $id;" + block() + controller.log += "after $id;" + } + + override fun

dispatchResume(data: P, continuation: Continuation

): Boolean { + dispatchResume { + continuation.resume(data) + } + return true + } + + override fun dispatchResumeWithException(exception: Throwable, continuation: Continuation<*>): Boolean { + dispatchResume { + continuation.resumeWithException(exception) + } + return true + } + }) + return controller.log +} + +fun box(): String { + var result = test { + val o = suspendWithValue("O") + val k = suspendWithValue("K") + log += "$o$k;" + } + if (result != "before 0;suspend(O);before 1;suspend(K);before 2;OK;after 2;after 1;after 0;") return "fail1: $result" + + result = test { + try { + suspendWithException("OK") + log += "ignore;" + } + catch (e: RuntimeException) { + log += "${e.message};" + } + } + if (result != "before 0;error(OK);before 1;OK;after 1;after 0;") return "fail2: $result" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/emptyClosure.kt b/backend.native/tests/external/codegen/blackbox/coroutines/emptyClosure.kt new file mode 100644 index 00000000000..9a648c512c0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/emptyClosure.kt @@ -0,0 +1,31 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +var result = 0 + +class Controller { + suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + result++ + x.resume("OK") + CoroutineIntrinsics.SUSPENDED + } +} + + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +fun box(): String { + + for (i in 1..3) { + builder { + if (suspendHere() != "OK") throw RuntimeException("fail 1") + } + } + + if (result != 3) return "fail 2: $result" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/falseUnitCoercion.kt b/backend.native/tests/external/codegen/blackbox/coroutines/falseUnitCoercion.kt new file mode 100644 index 00000000000..a2a1d712017 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/falseUnitCoercion.kt @@ -0,0 +1,29 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(v: T): T = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(v) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +var result: Any = "" + +fun foo(v: T) { + builder { + val r = suspendHere(v) + suspendHere("") + result = r + } +} + +fun box(): String { + foo("OK") + return result as String +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/generate.kt b/backend.native/tests/external/codegen/blackbox/coroutines/generate.kt new file mode 100644 index 00000000000..47c94806875 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/generate.kt @@ -0,0 +1,59 @@ +// WITH_RUNTIME +// WITH_COROUTINES +// FULL_JDK +import kotlin.coroutines.* + +fun box(): String { + val x = gen().joinToString() + if (x != "1, 2") return "fail1: $x" + + val y = gen().joinToString() + if (y != "-1") return "fail2: $y" + return "OK" +} + +var was = false + +fun gen() = generate { + if (was) { + yield(-1) + return@generate + } + for (i in 1..2) { + yield(i) + } + was = true +} + +// LIBRARY CODE +interface Generator { + suspend fun yield(value: T) +} + +fun generate(block: suspend Generator.() -> Unit): Sequence = GeneratedSequence(block) + +class GeneratedSequence(private val block: suspend Generator.() -> Unit) : Sequence { + override fun iterator(): Iterator = GeneratedIterator(block) +} + +class GeneratedIterator(block: suspend Generator.() -> Unit) : AbstractIterator(), Generator { + private var nextStep: Continuation = block.createCoroutine(this, object : Continuation { + override fun resume(data: Unit) { + done() + } + + override fun resumeWithException(exception: Throwable) { + throw exception + } + }) + + override fun computeNext() { + nextStep.resume(Unit) + } + suspend override fun yield(value: T) = CoroutineIntrinsics.suspendCoroutineOrReturn { c -> + setNext(value) + nextStep = c + + CoroutineIntrinsics.SUSPENDED + } +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/handleException.kt b/backend.native/tests/external/codegen/blackbox/coroutines/handleException.kt new file mode 100644 index 00000000000..56935d5bbeb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/handleException.kt @@ -0,0 +1,80 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + var exception: Throwable? = null + val postponedActions = ArrayList<() -> Unit>() + + suspend fun suspendWithValue(v: String): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + postponedActions.add { + x.resume(v) + } + + CoroutineIntrinsics.SUSPENDED + } + + suspend fun suspendWithException(e: Exception): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + postponedActions.add { + x.resumeWithException(e) + } + + CoroutineIntrinsics.SUSPENDED + } + + fun run(c: suspend Controller.() -> Unit) { + c.startCoroutine(this, handleExceptionContinuation { + exception = it + }) + while (postponedActions.isNotEmpty()) { + postponedActions[0]() + postponedActions.removeAt(0) + } + } +} + +fun builder(c: suspend Controller.() -> Unit) { + val controller = Controller() + controller.run(c) + + if (controller.exception?.message != "OK") { + throw RuntimeException("Unexpected result: ${controller.exception?.message}") + } +} + +fun commonThrow(t: Throwable) { + throw t +} + +fun box(): String { + builder { + throw RuntimeException("OK") + } + + builder { + commonThrow(RuntimeException("OK")) + } + + builder { + suspendWithException(RuntimeException("OK")) + } + + builder { + try { + suspendWithException(RuntimeException("fail 1")) + } catch (e: RuntimeException) { + suspendWithException(RuntimeException("OK")) + } + } + + builder { + try { + suspendWithException(Exception("OK")) + } catch (e: RuntimeException) { + suspendWithException(RuntimeException("fail 3")) + throw RuntimeException("fail 4") + } + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/handleResultCallEmptyBody.kt b/backend.native/tests/external/codegen/blackbox/coroutines/handleResultCallEmptyBody.kt new file mode 100644 index 00000000000..2efaebac409 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/handleResultCallEmptyBody.kt @@ -0,0 +1,19 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + + +fun builder(c: suspend () -> Unit): String { + var ok = false + c.startCoroutine(handleResultContinuation { + ok = true + }) + if (!ok) throw RuntimeException("Was not called") + return "OK" +} + +fun unitFun() {} + +fun box(): String { + return builder {} +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/handleResultNonUnitExpression.kt b/backend.native/tests/external/codegen/blackbox/coroutines/handleResultNonUnitExpression.kt new file mode 100644 index 00000000000..0943e13080a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/handleResultNonUnitExpression.kt @@ -0,0 +1,29 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + + +suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume("OK") + CoroutineIntrinsics.SUSPENDED +} + +fun builder(c: suspend () -> Unit) { + var isCompleted = false + c.startCoroutine(handleResultContinuation { + isCompleted = true + }) + if (!isCompleted) throw RuntimeException("fail") +} + +fun box(): String { + builder { + "OK" + } + + builder { + suspendHere() + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/handleResultSuspended.kt b/backend.native/tests/external/codegen/blackbox/coroutines/handleResultSuspended.kt new file mode 100644 index 00000000000..c97385948e3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/handleResultSuspended.kt @@ -0,0 +1,29 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + var log = "" + + suspend fun suspendAndLog(value: T): T = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + log += "suspend($value);" + x.resume(value) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> String): String { + val controller = Controller() + c.startCoroutine(controller, handleResultContinuation { + controller.log += "return($it);" + }) + return controller.log +} + +fun box(): String { + val result = builder { suspendAndLog("OK") } + + if (result != "suspend(OK);return(OK);") return "fail: $result" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/illegalState.kt b/backend.native/tests/external/codegen/blackbox/coroutines/illegalState.kt new file mode 100644 index 00000000000..88cb58acb02 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/illegalState.kt @@ -0,0 +1,63 @@ +// WITH_RUNTIME +// WITH_COROUTINES +// TARGET_BACKEND: JVM +import kotlin.coroutines.* + +suspend fun suspendHere(): Unit = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(Unit) + CoroutineIntrinsics.SUSPENDED +} + +fun builder1(c: suspend () -> Unit) { + (c as Continuation).resume(Unit) +} + +fun builder2(c: suspend () -> Unit) { + val continuation = c.createCoroutine(EmptyContinuation) + val declaredField = continuation.javaClass.superclass.superclass.getDeclaredField("label") + declaredField.setAccessible(true) + declaredField.set(continuation, -3) + continuation.resume(Unit) +} + +fun box(): String { + + try { + builder1 { + suspendHere() + } + return "fail 1" + } catch (e: kotlin.KotlinNullPointerException) { + } + + try { + builder2 { + suspendHere() + } + return "fail 3" + } catch (e: java.lang.IllegalStateException) { + if (e.message != "call to 'resume' before 'invoke' with coroutine") return "fail 4: ${e.message!!}" + } + + var result = "OK" + + try { + builder1 { + result = "fail 5" + } + return "fail 6" + } catch (e: kotlin.KotlinNullPointerException) { + } + + try { + builder2 { + result = "fail 8" + } + return "fail 9" + } catch (e: java.lang.IllegalStateException) { + if (e.message != "call to 'resume' before 'invoke' with coroutine") return "fail 10: ${e.message!!}" + return result + } + + return "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/inlineSuspendFunction.kt b/backend.native/tests/external/codegen/blackbox/coroutines/inlineSuspendFunction.kt new file mode 100644 index 00000000000..ec2de0105a3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/inlineSuspendFunction.kt @@ -0,0 +1,44 @@ +// WITH_RUNTIME +// WITH_COROUTINES +// WITH_REFLECT +// CHECK_NOT_CALLED: suspendInline_61zpoe$ +// CHECK_NOT_CALLED: suspendInline_6r51u9$ +// CHECK_NOT_CALLED: suspendInline +import kotlin.coroutines.* + +class Controller { + fun withValue(v: String, x: Continuation) { + x.resume(v) + } + + suspend inline fun suspendInline(v: String): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + withValue(v, x) + CoroutineIntrinsics.SUSPENDED + } + + suspend inline fun suspendInline(crossinline b: () -> String): String = suspendInline(b()) + + suspend inline fun suspendInline(): String = suspendInline({ T::class.simpleName!! }) +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +class OK + +fun box(): String { + var result = "" + + builder { + result = suspendInline("56") + if (result != "56") throw RuntimeException("fail 1") + + result = suspendInline { "57" } + if (result != "57") throw RuntimeException("fail 2") + + result = suspendInline() + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/inlinedTryCatchFinally.kt b/backend.native/tests/external/codegen/blackbox/coroutines/inlinedTryCatchFinally.kt new file mode 100644 index 00000000000..43029d735ec --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/inlinedTryCatchFinally.kt @@ -0,0 +1,160 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +var globalResult = "" +var wasCalled = false +class Controller { + val postponedActions = mutableListOf<() -> Unit>() + + suspend fun suspendWithValue(v: String): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + postponedActions.add { + x.resume(v) + } + + CoroutineIntrinsics.SUSPENDED + } + + suspend fun suspendWithException(e: Exception): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + postponedActions.add { + x.resumeWithException(e) + } + + CoroutineIntrinsics.SUSPENDED + } + + fun run(c: suspend Controller.() -> String) { + c.startCoroutine(this, handleResultContinuation { + globalResult = it + }) + while (postponedActions.isNotEmpty()) { + postponedActions[0]() + postponedActions.removeAt(0) + } + } +} + +fun builder(expectException: Boolean = false, c: suspend Controller.() -> String) { + val controller = Controller() + + globalResult = "#" + wasCalled = false + if (!expectException) { + controller.run(c) + } + else { + try { + controller.run(c) + globalResult = "fail: exception was not thrown" + } catch (e: Exception) { + globalResult = e.message!! + } + } + + if (!wasCalled) { + throw RuntimeException("fail wasCalled") + } + + if (globalResult != "OK") { + throw RuntimeException("fail $globalResult") + } +} + +fun commonThrow(t: Throwable) { + throw t +} + +inline fun tryCatch(t: () -> String, onException: (Exception) -> String) = + try { + t() + } catch (e: RuntimeException) { + onException(e) + } + +inline fun tryCatchFinally(t: () -> String, onException: (Exception) -> String, f: () -> Unit) = + try { + t() + } catch (e: RuntimeException) { + onException(e) + } finally { + f() + } + +fun box(): String { + builder { + tryCatch( + { + suspendWithValue("") + wasCalled = true + suspendWithValue("OK") + }, + { e -> + suspendWithValue("fail 1") + } + ) + } + + builder { + tryCatch( + { + suspendWithException(RuntimeException("M")) + }, + { e -> + if (e.message != "M") throw RuntimeException("fail 2") + wasCalled = true + suspendWithValue("OK") + } + ) + } + + builder { + tryCatchFinally( + { + suspendWithValue("") + wasCalled = true + suspendWithValue("OK") + }, + { + suspendWithValue("fail 1") + }, + { + suspendWithValue("ignored 1") + wasCalled = true + } + ) + } + + builder { + tryCatchFinally( + { + suspendWithException(RuntimeException("M")) + }, + { e -> + if (e.message != "M") throw RuntimeException("fail 2") + suspendWithValue("OK") + }, + { + suspendWithValue("ignored 2") + wasCalled = true + } + ) + } + + builder { + tryCatchFinally( + { + if (suspendWithValue("56") == "56") return@tryCatchFinally "OK" + suspendWithValue("fail 4") + }, + { + suspendWithValue("fail 5") + }, + { + suspendWithValue("ignored 3") + wasCalled = true + } + ) + } + + return globalResult +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/innerSuspensionCalls.kt b/backend.native/tests/external/codegen/blackbox/coroutines/innerSuspensionCalls.kt new file mode 100644 index 00000000000..19de56f9200 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/innerSuspensionCalls.kt @@ -0,0 +1,40 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + var i = 0 + suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume((i++).toString()) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +fun box(): String { + var result = "" + + builder { + result += "-" + result += suspendHere() + + if (result == "-0") { + builder { + result += "+" + result += suspendHere() + result += suspendHere() + result += "#" + } + + result += suspendHere() + result += "&" + } + } + + if (result != "-0+01#1&") return "fail: $result" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/instanceOfContinuation.kt b/backend.native/tests/external/codegen/blackbox/coroutines/instanceOfContinuation.kt new file mode 100644 index 00000000000..dab09664ad8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/instanceOfContinuation.kt @@ -0,0 +1,34 @@ +// WITH_RUNTIME +// WITH_COROUTINES +// WITH_REFLECT +import kotlin.coroutines.* + +class Controller { + suspend fun runInstanceOf(): Boolean = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + val y: Any = x + x.resume(x is Continuation<*>) + CoroutineIntrinsics.SUSPENDED + } + + suspend fun runCast(): Boolean = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + val y: Any = x + x.resume(Continuation::class.isInstance(y as Continuation<*>)) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +fun box(): String { + var result = "" + + builder { + result = runInstanceOf().toString() + "," + runCast().toString() + } + + if (result != "true,true") return "fail: $result" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/complicatedMerge.kt b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/complicatedMerge.kt new file mode 100644 index 00000000000..86a5c981bac --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/complicatedMerge.kt @@ -0,0 +1,34 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): Unit = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(Unit) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +fun foo() = true + +private var booleanResult = false +fun setBooleanRes(x: Boolean) { + booleanResult = x +} + +fun box(): String { + builder { + val x = true + val y = false + suspendHere() + setBooleanRes(if (foo()) x else y) + } + + if (!booleanResult) return "fail 1" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/i2bResult.kt b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/i2bResult.kt new file mode 100644 index 00000000000..32eaf28ec3f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/i2bResult.kt @@ -0,0 +1,33 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): Unit = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(Unit) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +private var byteResult: Byte = 0 +fun setByteRes(x: Byte) { + byteResult = x +} + +fun foo(): Int = 1 + +fun box(): String { + builder { + val x: Byte = foo().toByte() + suspendHere() + setByteRes(x) + } + + if (byteResult != 1.toByte()) return "fail 1" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/loadFromBooleanArray.kt b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/loadFromBooleanArray.kt new file mode 100644 index 00000000000..48bc273b3ea --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/loadFromBooleanArray.kt @@ -0,0 +1,32 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): Unit = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(Unit) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +private var booleanResult = false +fun setBooleanRes(x: Boolean) { + booleanResult = x +} + +fun box(): String { + builder { + val a = booleanArrayOf(true) + val x = a[0] + suspendHere() + setBooleanRes(x) + } + + if (!booleanResult) return "fail 1" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/loadFromByteArray.kt b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/loadFromByteArray.kt new file mode 100644 index 00000000000..d9e615db484 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/loadFromByteArray.kt @@ -0,0 +1,32 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): Unit = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(Unit) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +private var byteResult: Byte = 0 +fun setByteRes(x: Byte) { + byteResult = x +} + +fun box(): String { + builder { + val a = byteArrayOf(1) + val x = a[0] + suspendHere() + setByteRes(x) + } + + if (byteResult != 1.toByte()) return "fail 1" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/noVariableInTable.kt b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/noVariableInTable.kt new file mode 100644 index 00000000000..5ba69a2ee1c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/noVariableInTable.kt @@ -0,0 +1,32 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): Unit = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(Unit) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +private var booleanResult = false +fun setBooleanRes(x: Boolean, ignored: Unit) { + booleanResult = x +} + +fun box(): String { + builder { + // 'true' value is spilled into variable and saved to field before suspension point + // It's important that there is no type info about this variable in local var table, + // so we should infer that ICONST_1 is a boolean value from it's usage + setBooleanRes(true, suspendHere()) + } + + if (!booleanResult) return "fail 1" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/sameIconst1ManyVars.kt b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/sameIconst1ManyVars.kt new file mode 100644 index 00000000000..87a8b21cbf7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/sameIconst1ManyVars.kt @@ -0,0 +1,35 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): Unit = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(Unit) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +private var result: String = "" +fun setRes(x: Byte, y: Int) { + result = "$x#$y" +} + +fun foo(): Int = 1 + +fun box(): String { + builder { + val x: Byte = 1 + // No actual cast happens here + val y: Int = x.toInt() + suspendHere() + setRes(x, y) + } + + if (result != "1#1") return "fail 1" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/usedInArrayStore.kt b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/usedInArrayStore.kt new file mode 100644 index 00000000000..96eda9cfad5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/usedInArrayStore.kt @@ -0,0 +1,79 @@ +// WITH_RUNTIME +// WITH_COROUTINES +// TARGET_BACKEND: JVM +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): Unit = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(Unit) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +@JvmField +var booleanResult = booleanArrayOf() +@JvmField +var charResult = charArrayOf() +@JvmField +var byteResult = byteArrayOf() +@JvmField +var shortResult = shortArrayOf() +@JvmField +var intResult = intArrayOf() + +fun box(): String { + builder { + val x = true + suspendHere() + val a = BooleanArray(1) + a[0] = x + booleanResult = a + } + + if (!booleanResult[0]) return "fail 1" + + builder { + val x = '1' + suspendHere() + val a = CharArray(1) + a[0] = x + charResult = a + } + + if (charResult[0] != '1') return "fail 2" + + builder { + val x: Byte = 1 + suspendHere() + val a = ByteArray(1) + a[0] = x + byteResult = a + } + + if (byteResult[0] != 1.toByte()) return "fail 3" + + builder { + val x: Short = 1 + suspendHere() + val a = ShortArray(1) + a[0] = x + shortResult = a + } + + if (shortResult[0] != 1.toShort()) return "fail 4" + + builder { + val x: Int = 1 + suspendHere() + val a = IntArray(1) + a[0] = x + intResult = a + } + + if (intResult[0] != 1) return "fail 5" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/usedInMethodCall.kt b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/usedInMethodCall.kt new file mode 100644 index 00000000000..2de332b53a2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/usedInMethodCall.kt @@ -0,0 +1,82 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): Unit = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(Unit) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +private var booleanResult = false +fun setBooleanRes(x: Boolean) { + booleanResult = x +} + +private var charResult: Char = '0' +fun setCharRes(x: Char) { + charResult = x +} + +private var byteResult: Byte = 0 +fun setByteRes(x: Byte) { + byteResult = x +} + +private var shortResult: Short = 0 +fun setShortRes(x: Short) { + shortResult = x +} + +private var intResult: Int = 0 +fun setIntRes(x: Int) { + intResult = x +} + +fun box(): String { + builder { + val x = true + suspendHere() + setBooleanRes(x) + } + + if (!booleanResult) return "fail 1" + + builder { + val x = '1' + suspendHere() + setCharRes(x) + } + + if (charResult != '1') return "fail 2" + + builder { + val x: Byte = 1 + suspendHere() + setByteRes(x) + } + + if (byteResult != 1.toByte()) return "fail 3" + + builder { + val x: Short = 1 + suspendHere() + setShortRes(x) + } + + if (shortResult != 1.toShort()) return "fail 4" + + builder { + val x: Int = 1 + suspendHere() + setIntRes(x) + } + + if (intResult != 1) return "fail 5" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/usedInPutfield.kt b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/usedInPutfield.kt new file mode 100644 index 00000000000..47aeadcf71d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/usedInPutfield.kt @@ -0,0 +1,69 @@ +// WITH_RUNTIME +// WITH_COROUTINES +// TARGET_BACKEND: JVM +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): Unit = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(Unit) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +@JvmField +var booleanResult = false +@JvmField +var charResult: Char = '0' +@JvmField +var byteResult: Byte = 0 +@JvmField +var shortResult: Short = 0 +@JvmField +var intResult: Int = 0 + +fun box(): String { + builder { + val x = true + suspendHere() + booleanResult = x + } + + if (!booleanResult) return "fail 1" + + builder { + val x = '1' + suspendHere() + charResult = x + } + + if (charResult != '1') return "fail 2" + + builder { + val x: Byte = 1 + suspendHere() + byteResult = x + } + + if (byteResult != 1.toByte()) return "fail 3" + + builder { + val x: Short = 1 + suspendHere() + shortResult = x + } + + if (shortResult != 1.toShort()) return "fail 4" + + builder { + val x: Int = 1 + suspendHere() + intResult = x + } + + if (intResult != 1) return "fail 5" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/usedInVarStore.kt b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/usedInVarStore.kt new file mode 100644 index 00000000000..4568620869f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/intLikeVarSpilling/usedInVarStore.kt @@ -0,0 +1,58 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): Unit = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(Unit) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +fun box(): String { + builder { + val x = true + suspendHere() + val y: Boolean = x + if (!y) throw IllegalStateException("fail 1") + } + + builder { + val x = '1' + suspendHere() + + val y: Char = x + if (y != '1') throw IllegalStateException("fail 2") + } + + builder { + val x: Byte = 1 + suspendHere() + + val y: Byte = x + if (y != 1.toByte()) throw IllegalStateException("fail 3") + } + + builder { + val x: Short = 1 + + suspendHere() + + val y: Short = x + if (y != 1.toShort()) throw IllegalStateException("fail 4") + } + + builder { + val x: Int = 1 + suspendHere() + + val y: Int = x + if (y != 1) throw IllegalStateException("fail 5") + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/iterateOverArray.kt b/backend.native/tests/external/codegen/blackbox/coroutines/iterateOverArray.kt new file mode 100644 index 00000000000..a9bb1b5c742 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/iterateOverArray.kt @@ -0,0 +1,34 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume("OK") + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +fun box(): String { + val a = arrayOfNulls(2) as Array + a[0] = "O" + a[1] = "K" + var result = "" + + builder { + for (s in a) { + // 's' variable must be spilled before suspension point + // And it's important that it should be treated as a String instance because of 'result += s' after + // But BasicInterpreter just ignores type of argument array for AALOAD opcode (treating it's return type as plain Object), + // so we should refine the relevant part in our intepreter + if (suspendHere() != "OK") throw RuntimeException("fail 1") + result += s + } + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/kt12958.kt b/backend.native/tests/external/codegen/blackbox/coroutines/kt12958.kt new file mode 100644 index 00000000000..0ec9c8f8330 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/kt12958.kt @@ -0,0 +1,37 @@ +// WITH_RUNTIME +// WITH_COROUTINES +// WITH_CONTINUATION +import kotlin.coroutines.* + +suspend fun suspendHere(v: V): V = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(v) + CoroutineIntrinsics.SUSPENDED +} + +fun builder(c: suspend () -> String): String { + var result = "fail" + c.startCoroutine(handleResultContinuation { + result = it + }) + + return result +} + +fun foo(): String = builder { + // A piece of code for next statement: + // INVOKEVIRTUAL suspendHere + // CHECKCAST [B + // + // Analyzer uses `newValue` method for estimation of type generated by CHECKCAST insn, + // but for arrays `newValue` returned just Basic.REFERENCE_VALUE, thus we didn't add necessary checkcasts + // for variables spilled into fields + val data2 = suspendHere(ByteArray(2)) + + suspendHere("") + data2.size.toString() +} + +fun box(): String { + if (foo() != "2") return "fail 1" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/lastExpressionIsLoop.kt b/backend.native/tests/external/codegen/blackbox/coroutines/lastExpressionIsLoop.kt new file mode 100644 index 00000000000..965ec182d8a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/lastExpressionIsLoop.kt @@ -0,0 +1,54 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + var result = "" + var ok = false + suspend fun suspendHere(v: String): Unit = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + result += v + x.resume(Unit) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit): String { + val controller = Controller() + c.startCoroutine(controller, handleResultContinuation { + controller.ok = true + }) + if (!controller.ok) throw RuntimeException("Fail ok") + return controller.result +} + +fun box(): String { + val r1 = builder { + for (i in 5..6) { + suspendHere(i.toString()) + } + } + + if (r1 != "56") return "fail 1: $r1" + + val r2 = builder { + var i = 7 + while (i <= 8) { + suspendHere(i.toString()) + i++ + } + } + + if (r2 != "78") return "fail 2: $r2" + + val r3 = builder { + var i = 9 + do { + suspendHere(i.toString()) + i++ + } while (i <= 10); + } + + if (r3 != "910") return "fail 3: $r3" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/lastStatementInc.kt b/backend.native/tests/external/codegen/blackbox/coroutines/lastStatementInc.kt new file mode 100644 index 00000000000..b24c04d1cb3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/lastStatementInc.kt @@ -0,0 +1,43 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume("OK") + CoroutineIntrinsics.SUSPENDED +} + +fun builder(c: suspend () -> Unit) { + var wasHandleResultCalled = false + c.startCoroutine(handleResultContinuation { + wasHandleResultCalled = true + }) + + if (!wasHandleResultCalled) throw RuntimeException("fail 1") +} + +fun box(): String { + var result = 0 + + builder { + result++ + + if (suspendHere() != "OK") throw RuntimeException("fail 2") + + result-- + } + + if (result != 0) return "fail 3" + + builder { + --result + + if (suspendHere() != "OK") throw RuntimeException("fail 4") + + ++result + } + + if (result != 0) return "fail 5" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/lastStementAssignment.kt b/backend.native/tests/external/codegen/blackbox/coroutines/lastStementAssignment.kt new file mode 100644 index 00000000000..f04c11cede8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/lastStementAssignment.kt @@ -0,0 +1,45 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume("OK") + CoroutineIntrinsics.SUSPENDED +} + +fun builder(c: suspend () -> Unit) { + var wasHandleResultCalled = false + c.startCoroutine(handleResultContinuation { + wasHandleResultCalled = true + }) + + if (!wasHandleResultCalled) throw RuntimeException("fail 1") +} + +var varWithCustomSetter: String = "" + set(value) { + if (field != "") throw RuntimeException("fail 2") + field = value + } + +fun box(): String { + var result = "" + + builder { + result += "O" + + if (suspendHere() != "OK") throw RuntimeException("fail 3") + + result += "K" + } + + if (result != "OK") return "fail 4" + + builder { + if (suspendHere() != "OK") throw RuntimeException("fail 5") + + varWithCustomSetter = "OK" + } + + return varWithCustomSetter +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/lastUnitExpression.kt b/backend.native/tests/external/codegen/blackbox/coroutines/lastUnitExpression.kt new file mode 100644 index 00000000000..79e7352fe06 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/lastUnitExpression.kt @@ -0,0 +1,29 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + var ok = false + var v = "fail" + suspend fun suspendHere(v: String): Unit = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + this.v = v + x.resume(Unit) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit): String { + val controller = Controller() + c.startCoroutine(controller, handleResultContinuation { + controller.ok = true + }) + if (!controller.ok) throw RuntimeException("Fail 1") + return controller.v +} + +fun box(): String { + + return builder { + suspendHere("OK") + } +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/multiModule/inlineFunctionWithOptionalParam.kt b/backend.native/tests/external/codegen/blackbox/coroutines/multiModule/inlineFunctionWithOptionalParam.kt new file mode 100644 index 00000000000..fe81fa42641 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/multiModule/inlineFunctionWithOptionalParam.kt @@ -0,0 +1,30 @@ +// MODULE: lib +// FILE: lib.kt +inline fun foo(x: String = "OK"): String { + return x + x +} + +// MODULE: main(lib) +// FILE: main.kt +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +var result = "" + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(object : Continuation { + override fun resume(value: Unit) { + } + override fun resumeWithException(exception: Throwable) { + } + }) +} + +fun box(): String { + builder { + result = foo() + } + if (result != "OKOK") return "fail: $result" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/multiModule/simple.kt b/backend.native/tests/external/codegen/blackbox/coroutines/multiModule/simple.kt new file mode 100644 index 00000000000..3f7c8a605bc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/multiModule/simple.kt @@ -0,0 +1,33 @@ +// WITH_RUNTIME +// WITH_COROUTINES +// MODULE: controller +// FILE: controller.kt +package lib + +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume("OK") + CoroutineIntrinsics.SUSPENDED + } +} + +// MODULE: main(controller, support) +// FILE: main.kt +import lib.* +import kotlin.coroutines.* + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +fun box(): String { + var result = "" + + builder { + result = suspendHere() + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/multipleInvokeCalls.kt b/backend.native/tests/external/codegen/blackbox/coroutines/multipleInvokeCalls.kt new file mode 100644 index 00000000000..892ea72c0bd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/multipleInvokeCalls.kt @@ -0,0 +1,101 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + var lastSuspension: Continuation? = null + var result = "fail" + suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + lastSuspension = x + CoroutineIntrinsics.SUSPENDED + } + + fun hasNext() = lastSuspension != null + fun next() { + val x = lastSuspension!! + lastSuspension = null + x.resume("56") + } +} + +fun builder(c: suspend Controller.() -> Unit) { + val controller1 = Controller() + val controller2 = Controller() + + c.startCoroutine(controller1, EmptyContinuation) + c.startCoroutine(controller2, EmptyContinuation) + + runControllers(controller1, controller2) +} + +// TODO: additional parameters are not supported yet +//fun builder2(coroutine c: Controller.(Long, String) -> Continuation) { +// val controller1 = Controller() +// val controller2 = Controller() +// +// c(controller1, 1234567890123456789L, "Q").resume(Unit) +// c(controller2, 1234567890123456789L, "Q").resume(Unit) +// +// runControllers(controller1, controller2) +//} + +private fun runControllers(controller1: Controller, controller2: Controller) { + while (controller1.hasNext()) { + if (!controller2.hasNext()) throw RuntimeException("fail 1") + + if (controller1.lastSuspension === controller2.lastSuspension) throw RuntimeException("equal references") + + controller1.next() + controller2.next() + } + + if (controller2.hasNext()) throw RuntimeException("fail 2") + + if (controller1.result != "OK") throw RuntimeException("fail 3") + if (controller2.result != "OK") throw RuntimeException("fail 4") +} + +fun box(): String { + // no suspension + builder { + result = "OK" + } + + // 1 suspension + builder { + if (suspendHere() != "56") return@builder + result = "OK" + } + + // 2 suspensions + builder { + if (suspendHere() != "56") return@builder + suspendHere() + result = "OK" + } + + // with capture + + var x = "O" + var y = "K" + + // no suspension + builder { + result = x + y + } + + // 1 suspension + builder { + if (suspendHere() != "56") return@builder + result = x + y + } + + // 2 suspensions + builder { + if (suspendHere() != "56") return@builder + suspendHere() + result = x + y + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/multipleInvokeCallsInsideInlineLambda1.kt b/backend.native/tests/external/codegen/blackbox/coroutines/multipleInvokeCallsInsideInlineLambda1.kt new file mode 100644 index 00000000000..3926e11eb52 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/multipleInvokeCallsInsideInlineLambda1.kt @@ -0,0 +1,90 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + var lastSuspension: Continuation? = null + var result = "fail" + suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + lastSuspension = x + CoroutineIntrinsics.SUSPENDED + } + + fun hasNext() = lastSuspension != null + fun next() { + val x = lastSuspension!! + lastSuspension = null + x.resume("56") + } +} + +fun builder(c: suspend Controller.() -> Unit) { + val controller1 = Controller() + val controller2 = Controller() + + c.startCoroutine(controller1, EmptyContinuation) + c.startCoroutine(controller2, EmptyContinuation) + + runControllers(controller1, controller2) +} + +// TODO: additional parameters are not supported yet +//fun builder2(coroutine c: Controller.(Long, String) -> Continuation) { +// val controller1 = Controller() +// val controller2 = Controller() +// +// c(controller1, 1234567890123456789L, "Q").resume(Unit) +// c(controller2, 1234567890123456789L, "Q").resume(Unit) +// +// runControllers(controller1, controller2) +//} + +private fun runControllers(controller1: Controller, controller2: Controller) { + while (controller1.hasNext()) { + if (!controller2.hasNext()) throw RuntimeException("fail 1") + + if (controller1.lastSuspension === controller2.lastSuspension) throw RuntimeException("equal references") + + controller1.next() + controller2.next() + } + + if (controller2.hasNext()) throw RuntimeException("fail 2") + + if (controller1.result != "OK") throw RuntimeException("fail 3") + if (controller2.result != "OK") throw RuntimeException("fail 4") +} + +inline fun run(b: () -> Unit) { + b() +} + +fun box(): String { + // with capture and params + + var x = "O" + var y = "K" + + // inlined + run { + // no suspension + builder { + result = x + y + } + + // 1 suspension + builder { + if (suspendHere() != "56") return@builder + result = x + y + } + + // 2 suspensions + builder { + if (suspendHere() != "56") return@builder + suspendHere() + result = x + y + } + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/multipleInvokeCallsInsideInlineLambda2.kt b/backend.native/tests/external/codegen/blackbox/coroutines/multipleInvokeCallsInsideInlineLambda2.kt new file mode 100644 index 00000000000..fdf83f31294 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/multipleInvokeCallsInsideInlineLambda2.kt @@ -0,0 +1,92 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + var lastSuspension: Continuation? = null + var result = "fail" + suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + lastSuspension = x + CoroutineIntrinsics.SUSPENDED + } + + fun hasNext() = lastSuspension != null + fun next() { + val x = lastSuspension!! + lastSuspension = null + x.resume("56") + } +} + +fun builder(c: suspend Controller.() -> Unit) { + val controller1 = Controller() + val controller2 = Controller() + + c.startCoroutine(controller1, EmptyContinuation) + c.startCoroutine(controller2, EmptyContinuation) + + runControllers(controller1, controller2) +} + +// TODO: additional parameters are not supported yet +//fun builder2(coroutine c: Controller.(Long, String) -> Continuation) { +// val controller1 = Controller() +// val controller2 = Controller() +// +// c(controller1, 1234567890123456789L, "Q").resume(Unit) +// c(controller2, 1234567890123456789L, "Q").resume(Unit) +// +// runControllers(controller1, controller2) +//} + +private fun runControllers(controller1: Controller, controller2: Controller) { + while (controller1.hasNext()) { + if (!controller2.hasNext()) throw RuntimeException("fail 1") + + if (controller1.lastSuspension === controller2.lastSuspension) throw RuntimeException("equal references") + + controller1.next() + controller2.next() + } + + if (controller2.hasNext()) throw RuntimeException("fail 2") + + if (controller1.result != "OK") throw RuntimeException("fail 3") + if (controller2.result != "OK") throw RuntimeException("fail 4") +} + +inline fun run(b: () -> Unit) { + b() +} + +fun box(): String { + // with capture and params + var x = "O" + + // inlined + run { + var y = "K" + + { + // no suspension + builder { + result = "OK" + } + + // 1 suspension + builder { + if (suspendHere() != "56") return@builder + result = "OK" + } + + // 2 suspensions + builder { + if (suspendHere() != "56") return@builder + suspendHere() + result = "OK" + } + }() + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/multipleInvokeCallsInsideInlineLambda3.kt b/backend.native/tests/external/codegen/blackbox/coroutines/multipleInvokeCallsInsideInlineLambda3.kt new file mode 100644 index 00000000000..5dac65520ee --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/multipleInvokeCallsInsideInlineLambda3.kt @@ -0,0 +1,90 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + var lastSuspension: Continuation? = null + var result = "fail" + suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + lastSuspension = x + CoroutineIntrinsics.SUSPENDED + } + + fun hasNext() = lastSuspension != null + fun next() { + val x = lastSuspension!! + lastSuspension = null + x.resume("56") + } +} + +fun builder(c: suspend Controller.() -> Unit) { + val controller1 = Controller() + val controller2 = Controller() + + c.startCoroutine(controller1, EmptyContinuation) + c.startCoroutine(controller2, EmptyContinuation) + + runControllers(controller1, controller2) +} + +// TODO: additional parameters are not supported yet +//fun builder2(coroutine c: Controller.(Long, String) -> Continuation) { +// val controller1 = Controller() +// val controller2 = Controller() +// +// c(controller1, 1234567890123456789L, "Q").resume(Unit) +// c(controller2, 1234567890123456789L, "Q").resume(Unit) +// +// runControllers(controller1, controller2) +//} + +private fun runControllers(controller1: Controller, controller2: Controller) { + while (controller1.hasNext()) { + if (!controller2.hasNext()) throw RuntimeException("fail 1") + + if (controller1.lastSuspension === controller2.lastSuspension) throw RuntimeException("equal references") + + controller1.next() + controller2.next() + } + + if (controller2.hasNext()) throw RuntimeException("fail 2") + + if (controller1.result != "OK") throw RuntimeException("fail 3") + if (controller2.result != "OK") throw RuntimeException("fail 4") +} + +inline fun run(b: () -> Unit) { + b() +} + +fun box(): String { + var x = "O" + + { + var y = "K" + // inlined + run { + // no suspension + builder { + result = "OK" + } + + // 1 suspension + builder { + if (suspendHere() != "56") return@builder + result = "OK" + } + + // 2 suspensions + builder { + if (suspendHere() != "56") return@builder + suspendHere() + result = "OK" + } + } + } () + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/nestedTryCatch.kt b/backend.native/tests/external/codegen/blackbox/coroutines/nestedTryCatch.kt new file mode 100644 index 00000000000..2e7b27f929e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/nestedTryCatch.kt @@ -0,0 +1,114 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +var globalResult = "" +var wasCalled = false +class Controller { + val postponedActions = ArrayList<() -> Unit>() + + suspend fun suspendWithValue(v: String): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + postponedActions.add { + x.resume(v) + } + + CoroutineIntrinsics.SUSPENDED + } + + suspend fun suspendWithException(e: Exception): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + postponedActions.add { + x.resumeWithException(e) + } + + CoroutineIntrinsics.SUSPENDED + } + + fun run(c: suspend Controller.() -> String) { + c.startCoroutine(this, handleResultContinuation { + globalResult = it + }) + while (postponedActions.isNotEmpty()) { + postponedActions[0]() + postponedActions.removeAt(0) + } + } +} + +fun builder(expectException: Boolean = false, c: suspend Controller.() -> String) { + val controller = Controller() + + globalResult = "#" + wasCalled = false + if (!expectException) { + controller.run(c) + } + else { + try { + controller.run(c) + globalResult = "fail: exception was not thrown" + } catch (e: Exception) { + globalResult = e.message!! + } + } + + if (!wasCalled) { + throw RuntimeException("fail wasCalled") + } + + if (globalResult != "OK") { + throw RuntimeException("fail $globalResult") + } +} + +fun commonThrow(t: Throwable) { + throw t +} + +fun box(): String { + builder { + try { + try { + suspendWithValue("") + suspendWithValue("OK") + } + catch (e: RuntimeException) { + suspendWithValue("fail 1") + } + } finally { + wasCalled = true + } + } + + builder { + try { + try { + suspendWithException(RuntimeException("M1")) + } + catch (e: RuntimeException) { + if (e.message != "M1") throw RuntimeException("fail 2") + wasCalled = true + suspendWithValue("OK") + } + } catch (e: Exception) { + suspendWithValue("fail 3") + } + } + + builder { + try { + try { + suspendWithException(Exception("M2")) + } + catch (e: RuntimeException) { + suspendWithValue("fail 4") + } finally { + wasCalled = true + } + } catch (e: Exception) { + if (e.message != "M2") throw RuntimeException("fail 5") + suspendWithValue("OK") + } + } + + return globalResult +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/noSuspensionPoints.kt b/backend.native/tests/external/codegen/blackbox/coroutines/noSuspensionPoints.kt new file mode 100644 index 00000000000..5a8a13d4fe6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/noSuspensionPoints.kt @@ -0,0 +1,26 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + + +fun builder(c: suspend () -> Int): Int { + var res = 0 + c.startCoroutine(handleResultContinuation { + res = it + }) + + return res +} + +fun box(): String { + var result = "" + + val handledResult = builder { + result = "OK" + 56 + } + + if (handledResult != 56) return "fail 1: $handledResult" + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/nonLocalReturnFromInlineLambda.kt b/backend.native/tests/external/codegen/blackbox/coroutines/nonLocalReturnFromInlineLambda.kt new file mode 100644 index 00000000000..ac8d1592ed7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/nonLocalReturnFromInlineLambda.kt @@ -0,0 +1,46 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + var cResult = 0 + suspend fun suspendHere(v: Int): Int = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(v * 2) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Int): Controller { + val controller = Controller() + c.startCoroutine(controller, handleResultContinuation { + controller.cResult = it + }) + + return controller +} + +inline fun foo(x: (Int) -> Unit) { + for (i in 1..2) { + x(i) + } +} + +fun box(): String { + var result = "" + + val controllerResult = builder { + result += "-" + foo { + result += suspendHere(it).toString() + if (it == 2) return@builder 56 + } + // Should be unreachable + result += "+" + 1 + }.cResult + + if (result != "-24") return "fail 1: $result" + if (controllerResult != 56) return "fail 2: $controllerResult" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/nonLocalReturnFromInlineLambdaDeep.kt b/backend.native/tests/external/codegen/blackbox/coroutines/nonLocalReturnFromInlineLambdaDeep.kt new file mode 100644 index 00000000000..9c0de6fadad --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/nonLocalReturnFromInlineLambdaDeep.kt @@ -0,0 +1,51 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + + +class Controller { + var cResult = 0 + suspend fun suspendHere(v: Int): Int = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(v * 2) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Int): Controller { + val controller = Controller() + c.startCoroutine(controller, handleResultContinuation { + controller.cResult = it + }) + + return controller +} + +inline fun foo(x: (Int) -> Unit) { + for (i in 1..2) { + run { + x(i) + } + } +} + +fun box(): String { + var result = "" + + val controllerResult = builder { + result += "-" + foo { + run { + result += suspendHere(it).toString() + if (it == 2) return@builder 56 + } + } + // Should be unreachable + result += "+" + 1 + }.cResult + + if (result != "-24") return "fail 1: $result" + if (controllerResult != 56) return "fail 2: $controllerResult" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/returnByLabel.kt b/backend.native/tests/external/codegen/blackbox/coroutines/returnByLabel.kt new file mode 100644 index 00000000000..583aa33bbc8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/returnByLabel.kt @@ -0,0 +1,30 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume("OK") + CoroutineIntrinsics.SUSPENDED +} + +fun builder(c: suspend () -> Int): Int { + var res = 0 + c.startCoroutine(handleResultContinuation { + res = it + }) + + return res +} + +fun box(): String { + var result = "" + + val handledResult = builder { + result = suspendHere() + return@builder 56 + } + + if (handledResult != 56) return "fail 1: $handledResult" + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/simple.kt b/backend.native/tests/external/codegen/blackbox/coroutines/simple.kt new file mode 100644 index 00000000000..d640d67f0ba --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/simple.kt @@ -0,0 +1,22 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume("OK") + CoroutineIntrinsics.SUSPENDED +} + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +fun box(): String { + var result = "" + + builder { + result = suspendHere() + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/simpleException.kt b/backend.native/tests/external/codegen/blackbox/coroutines/simpleException.kt new file mode 100644 index 00000000000..06999f19879 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/simpleException.kt @@ -0,0 +1,29 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resumeWithException(RuntimeException("OK")) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +fun box(): String { + var result = "" + + builder { + try { + suspendHere() + result = "fail" + } catch (e: RuntimeException) { + result = "OK" + } + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/simpleWithHandleResult.kt b/backend.native/tests/external/codegen/blackbox/coroutines/simpleWithHandleResult.kt new file mode 100644 index 00000000000..d6f61c1fee3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/simpleWithHandleResult.kt @@ -0,0 +1,39 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume("OK") + CoroutineIntrinsics.SUSPENDED +} + +fun builder(c: suspend () -> Int): Int { + var res = 0 + + c.createCoroutine(object : Continuation { + override fun resume(data: Int) { + res = data + } + + override fun resumeWithException(exception: Throwable) { + throw exception + } + }).resume(Unit) + + return res +} + + + +fun box(): String { + var result = "" + + val handledResult = builder { + result = suspendHere() + 56 + } + + if (handledResult != 56) return "fail 1: $handledResult" + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/stackUnwinding/exception.kt b/backend.native/tests/external/codegen/blackbox/coroutines/stackUnwinding/exception.kt new file mode 100644 index 00000000000..04294aa9e4b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/stackUnwinding/exception.kt @@ -0,0 +1,21 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): String = throw RuntimeException("OK") +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +fun box(): String { + var result = "" + + builder { + result = try { suspendHere() } catch (e: RuntimeException) { e.message!! } + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/stackUnwinding/inlineSuspendFunction.kt b/backend.native/tests/external/codegen/blackbox/coroutines/stackUnwinding/inlineSuspendFunction.kt new file mode 100644 index 00000000000..6708e8a2714 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/stackUnwinding/inlineSuspendFunction.kt @@ -0,0 +1,37 @@ +// WITH_RUNTIME +// WITH_COROUTINES +// WITH_REFLECT +// CHECK_NOT_CALLED: suspendInline_61zpoe$ +// CHECK_NOT_CALLED: suspendInline_6r51u9$ +// CHECK_NOT_CALLED: suspendInline +import kotlin.coroutines.* + +class Controller { + suspend inline fun suspendInline(v: String): String = v + + suspend inline fun suspendInline(crossinline b: () -> String): String = suspendInline(b()) + + suspend inline fun suspendInline(): String = suspendInline({ T::class.simpleName!! }) +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +class OK + +fun box(): String { + var result = "" + + builder { + result = suspendInline("56") + if (result != "56") throw RuntimeException("fail 1") + + result = suspendInline { "57" } + if (result != "57") throw RuntimeException("fail 2") + + result = suspendInline() + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/stackUnwinding/simple.kt b/backend.native/tests/external/codegen/blackbox/coroutines/stackUnwinding/simple.kt new file mode 100644 index 00000000000..31e1bc7f640 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/stackUnwinding/simple.kt @@ -0,0 +1,21 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere() = "OK" +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +fun box(): String { + var result = "" + + builder { + result = suspendHere() + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/stackUnwinding/suspendInCycle.kt b/backend.native/tests/external/codegen/blackbox/coroutines/stackUnwinding/suspendInCycle.kt new file mode 100644 index 00000000000..7810fea43ec --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/stackUnwinding/suspendInCycle.kt @@ -0,0 +1,48 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): Int = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + 1 + } + suspend fun suspendThere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + "?" + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +fun box(): String { + var result = "" + + builder { + result += "-" + for (i in 0..10000) { + if (i % 2 == 0) { + result += suspendHere().toString() + } + else if (i == 3) { + result += suspendThere() + } + } + result += "+" + } + + var mustBe = "-" + for (i in 0..10000) { + if (i % 2 == 0) { + mustBe += "1" + } + else if (i == 3) { + mustBe += "?" + } + } + mustBe += "+" + + if (result != mustBe) return "fail: $result/$mustBe" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/statementLikeLastExpression.kt b/backend.native/tests/external/codegen/blackbox/coroutines/statementLikeLastExpression.kt new file mode 100644 index 00000000000..197969c80f2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/statementLikeLastExpression.kt @@ -0,0 +1,30 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +var globalResult = "" +suspend fun suspendWithValue(v: String): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(v) + CoroutineIntrinsics.SUSPENDED +} + +fun builder(c: suspend () -> String) { + c.startCoroutine(handleResultContinuation { + globalResult = it + }) +} + +fun box(): String { + + var condition = true + + builder { + if (condition) { + suspendWithValue("OK") + } else { + suspendWithValue("fail 1") + } + } + + return globalResult +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/suspendDelegation.kt b/backend.native/tests/external/codegen/blackbox/coroutines/suspendDelegation.kt new file mode 100644 index 00000000000..7e0b04a51fc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/suspendDelegation.kt @@ -0,0 +1,26 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): String = suspendThere() + + suspend fun suspendThere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume("OK") + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +fun box(): String { + var result = "" + + builder { + result = suspendHere() + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/suspendFromInlineLambda.kt b/backend.native/tests/external/codegen/blackbox/coroutines/suspendFromInlineLambda.kt new file mode 100644 index 00000000000..f77e3ac11b4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/suspendFromInlineLambda.kt @@ -0,0 +1,36 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(v: Int): Int = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(v * 2) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +inline fun foo(x: (Int) -> Unit) { + for (i in 1..2) { + x(i) + } +} + +fun box(): String { + var result = "" + + builder { + result += "-" + foo { + result += suspendHere(it).toString() + } + result += "+" + } + + if (result != "-24+") return "fail: $result" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/suspendFunctionTypeCall/manyParameters.kt b/backend.native/tests/external/codegen/blackbox/coroutines/suspendFunctionTypeCall/manyParameters.kt new file mode 100644 index 00000000000..de436c53998 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/suspendFunctionTypeCall/manyParameters.kt @@ -0,0 +1,30 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +suspend fun suspendHere(v: String): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(v) + CoroutineIntrinsics.SUSPENDED +} + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +suspend fun foo(c: suspend Double.(Long, Int, String) -> String) = (1.0).c(56L, 55, "abc") + +fun box(): String { + var result = "" + var final = "" + + builder { + final = foo { l, i, s -> + result = suspendHere("$this#$l#$i#$s") + "OK" + } + } + + if (result != "1.0#56#55#abc" && result != "1#56#55#abc") return "fail: $result" + + return final +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/suspendFunctionTypeCall/simple.kt b/backend.native/tests/external/codegen/blackbox/coroutines/suspendFunctionTypeCall/simple.kt new file mode 100644 index 00000000000..10c2b655e73 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/suspendFunctionTypeCall/simple.kt @@ -0,0 +1,36 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +suspend fun suspendHere(v: String): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(v) + CoroutineIntrinsics.SUSPENDED +} + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +suspend fun foo1(c: suspend () -> Unit) = c() +suspend fun foo2(c: suspend String.() -> Int) = "2".c() +suspend fun foo3(c: suspend (String) -> Int) = c("3") + +fun box(): String { + var result = "" + + builder { + foo1 { + result = suspendHere("begin#") + } + + val q2 = foo2 { result += suspendHere(this) + "#"; 1 } + val q3 = foo3 { result += suspendHere(it); 2 } + + if (q2 != 1) throw RuntimeException("fail q2") + if (q3 != 2) throw RuntimeException("fail q3") + } + + if (result != "begin#2#3") return "fail: $result" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/suspendInCycle.kt b/backend.native/tests/external/codegen/blackbox/coroutines/suspendInCycle.kt new file mode 100644 index 00000000000..d59e9c44fcf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/suspendInCycle.kt @@ -0,0 +1,40 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + var i = 0 + suspend fun suspendHere(): Int = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(i++) + CoroutineIntrinsics.SUSPENDED + } + suspend fun suspendThere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume("?") + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +fun box(): String { + var result = "" + + builder { + result += "-" + for (i in 0..5) { + if (i % 2 == 0) { + result += suspendHere().toString() + } + else if (i == 3) { + result += suspendThere() + } + } + result += "+" + } + + if (result != "-01?2+") return "fail: $result" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/suspendInTheMiddleOfObjectConstruction.kt b/backend.native/tests/external/codegen/blackbox/coroutines/suspendInTheMiddleOfObjectConstruction.kt new file mode 100644 index 00000000000..95114878c23 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/suspendInTheMiddleOfObjectConstruction.kt @@ -0,0 +1,98 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume("K") + CoroutineIntrinsics.SUSPENDED + } + + suspend fun suspendWithArgument(v: String): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(v) + CoroutineIntrinsics.SUSPENDED + } + + suspend fun suspendWithDouble(v: Double): Double = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(v) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +class A(val first: String, val second: String) { + override fun toString() = "$first$second" +} +class B(val first: String, val second: String, val third: String) { + override fun toString() = "$first$second$third" +} + +class C(val first: Long, val second: Double, val third: String) { + override fun toString() = "$first#$second#$third" +} + + +fun box(): String { + var result = "OK" + + builder { + var local: Any = A("O", suspendHere()) + + if (local.toString() != "OK") { + result = "fail 1: $local" + return@builder + } + + local = A(suspendWithArgument("O"), suspendHere()) + + if (local.toString() != "OK") { + result = "fail 2: $local" + return@builder + } + + local = B("#", suspendWithArgument("O"), suspendHere()) + + if (local.toString() != "#OK") { + result = "fail 3: $local" + return@builder + } + + local = B(suspendWithArgument("#"), "O", suspendHere()) + + if (local.toString() != "#OK") { + result = "fail 4: $local" + return@builder + } + + local = B("#", B("", "O", suspendWithArgument("")).toString(), suspendHere()) + + if (local.toString() != "#OK") { + result = "fail 5: $local" + return@builder + } + + val condition = local.toString() == "#OK" + + local = B( + if (!condition) "1" else suspendWithArgument("#"), + if (condition) suspendWithArgument("O") else "2", + if (condition) suspendHere() else suspendWithArgument("3")) + + if (local.toString() != "#OK") { + result = "fail 5: $local" + return@builder + } + + local = C(1234567890123L, suspendWithDouble(3.14), suspendWithArgument("OK")) + + if (local.toString() != "1234567890123#3.14#OK") { + result = "fail 5: $local" + return@builder + } + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/tryCatchFinallyWithHandleResult.kt b/backend.native/tests/external/codegen/blackbox/coroutines/tryCatchFinallyWithHandleResult.kt new file mode 100644 index 00000000000..c94ec80e3ba --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/tryCatchFinallyWithHandleResult.kt @@ -0,0 +1,177 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +var globalResult = "" +var wasCalled = false +class Controller { + val postponedActions = ArrayList<() -> Unit>() + + suspend fun suspendWithValue(v: String): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + postponedActions.add { + x.resume(v) + } + + CoroutineIntrinsics.SUSPENDED + } + + suspend fun suspendWithException(e: Exception): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + postponedActions.add { + x.resumeWithException(e) + } + + CoroutineIntrinsics.SUSPENDED + } + + fun run(c: suspend Controller.() -> String) { + c.startCoroutine(this, handleResultContinuation { + globalResult = it + }) + while (postponedActions.isNotEmpty()) { + postponedActions[0]() + postponedActions.removeAt(0) + } + } +} + +fun builder(expectException: Boolean = false, c: suspend Controller.() -> String) { + val controller = Controller() + + globalResult = "#" + wasCalled = false + if (!expectException) { + controller.run(c) + } + else { + try { + controller.run(c) + globalResult = "fail: exception was not thrown" + } catch (e: Exception) { + globalResult = e.message!! + } + } + + if (!wasCalled) { + throw RuntimeException("fail wasCalled") + } + + if (globalResult != "OK") { + throw RuntimeException("fail $globalResult") + } +} + +fun commonThrow(t: Throwable) { + throw t +} + +fun box(): String { + builder { + try { + suspendWithValue("") + suspendWithValue("OK") + } catch (e: RuntimeException) { + suspendWithValue("fail 1") + } finally { + suspendWithValue("ignored 1") + wasCalled = true + } + } + + builder { + try { + suspendWithException(RuntimeException("M")) + } catch (e: RuntimeException) { + if (e.message != "M") throw RuntimeException("fail 2") + suspendWithValue("OK") + } finally { + suspendWithValue("ignored 2") + wasCalled = true + } + } + + builder(expectException = true) { + try { + suspendWithException(Exception("OK")) + } catch (e: RuntimeException) { + suspendWithValue("fail") + throw RuntimeException("fail 3") + } finally { + suspendWithValue("ignored 3") + wasCalled = true + } + } + + builder(expectException = true) { + try { + suspendWithException(Exception("OK")) + } catch (e: RuntimeException) { + suspendWithValue("fail") + return@builder "xyz" + } finally { + suspendWithValue("ignored 4") + wasCalled = true + } + } + + builder { + try { + suspendWithException(Exception("M2")) + } catch (e: RuntimeException) { + suspendWithValue("fail") + throw RuntimeException("fail 4") + } catch (e: Exception) { + if (e.message != "M2") throw Exception("fail 5: ${e.message}") + suspendWithValue("OK") + } finally { + suspendWithValue("ignored 4") + wasCalled = true + } + } + + builder { + try { + suspendWithValue("123") + commonThrow(RuntimeException("M3")) + suspendWithValue("456") + } catch (e: RuntimeException) { + if (e.message != "M3") throw Exception("fail 6: ${e.message}") + suspendWithValue("OK") + } finally { + suspendWithValue("ignored 5") + wasCalled = true + } + } + + builder(expectException = true) { + try { + suspendWithValue("123") + commonThrow(Exception("OK")) + suspendWithValue("456") + } catch (e: RuntimeException) { + suspendWithValue("fail") + throw RuntimeException("fail 7") + } finally { + suspendWithValue("ignored 6") + wasCalled = true + } + } + + builder { + try { + suspendWithValue("123") + commonThrow(Exception("M3")) + suspendWithValue("456") + } catch (e: RuntimeException) { + suspendWithValue("fail") + throw RuntimeException("fail 8") + } catch (e: Exception) { + if (e.message != "M3") throw Exception("fail 9: ${e.message}") + suspendWithValue("OK") + } finally { + suspendWithValue("ignored 7") + wasCalled = true + } + } + + return globalResult +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/tryCatchWithHandleResult.kt b/backend.native/tests/external/codegen/blackbox/coroutines/tryCatchWithHandleResult.kt new file mode 100644 index 00000000000..8be35219df5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/tryCatchWithHandleResult.kt @@ -0,0 +1,151 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +var globalResult = "" +var wasCalled = false +class Controller { + val postponedActions = ArrayList<() -> Unit>() + + suspend fun suspendWithValue(v: String): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + postponedActions.add { + x.resume(v) + } + + CoroutineIntrinsics.SUSPENDED + } + + suspend fun suspendWithException(e: Exception): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + postponedActions.add { + x.resumeWithException(e) + } + + CoroutineIntrinsics.SUSPENDED + } + + fun run(c: suspend Controller.() -> String) { + c.startCoroutine(this, handleResultContinuation { + globalResult = it + }) + while (postponedActions.isNotEmpty()) { + postponedActions[0]() + postponedActions.removeAt(0) + } + } +} + +fun builder(expectException: Boolean = false, c: suspend Controller.() -> String) { + val controller = Controller() + + globalResult = "#" + wasCalled = false + if (!expectException) { + controller.run(c) + } + else { + try { + controller.run(c) + globalResult = "fail: exception was not thrown" + } catch (e: Exception) { + globalResult = e.message!! + } + } + + if (!wasCalled) { + throw RuntimeException("fail wasCalled") + } + + if (globalResult != "OK") { + throw RuntimeException("fail $globalResult") + } +} + +fun commonThrow(t: Throwable) { + throw t +} + +fun box(): String { + builder { + try { + suspendWithValue("") + wasCalled = true + suspendWithValue("OK") + } catch (e: RuntimeException) { + suspendWithValue("fail 1") + } + } + + builder { + try { + suspendWithException(RuntimeException("M")) + } catch (e: RuntimeException) { + if (e.message != "M") throw RuntimeException("fail 2") + wasCalled = true + suspendWithValue("OK") + } + } + + builder(expectException = true) { + try { + wasCalled = true + suspendWithException(Exception("OK")) + } catch (e: RuntimeException) { + suspendWithValue("fail") + throw RuntimeException("fail 3") + } + } + + builder { + try { + suspendWithException(Exception("M2")) + } catch (e: RuntimeException) { + suspendWithValue("fail") + throw RuntimeException("fail 4") + } catch (e: Exception) { + if (e.message != "M2") throw Exception("fail 5: ${e.message}") + wasCalled = true + suspendWithValue("OK") + } + } + + builder { + try { + suspendWithValue("123") + commonThrow(RuntimeException("M3")) + suspendWithValue("456") + } catch (e: RuntimeException) { + if (e.message != "M3") throw Exception("fail 6: ${e.message}") + wasCalled = true + suspendWithValue("OK") + } + } + + builder(expectException = true) { + try { + suspendWithValue("123") + wasCalled = true + commonThrow(Exception("OK")) + suspendWithValue("456") + } catch (e: RuntimeException) { + suspendWithValue("fail") + throw RuntimeException("fail 7") + } + } + + builder { + try { + suspendWithValue("123") + commonThrow(Exception("M3")) + suspendWithValue("456") + } catch (e: RuntimeException) { + suspendWithValue("fail") + throw RuntimeException("fail 8") + } catch (e: Exception) { + if (e.message != "M3") throw Exception("fail 9: ${e.message}") + wasCalled = true + suspendWithValue("OK") + } + } + + return globalResult +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/tryFinallyInsideInlineLambda.kt b/backend.native/tests/external/codegen/blackbox/coroutines/tryFinallyInsideInlineLambda.kt new file mode 100644 index 00000000000..202481ee123 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/tryFinallyInsideInlineLambda.kt @@ -0,0 +1,34 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(v: String): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(v) + + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +inline fun run(block: () -> Unit) { + block() +} + +fun box(): String { + var result = "" + run { + builder { + try { + result += suspendHere("O") + } finally { + result += suspendHere("K") + } + } + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/tryFinallyWithHandleResult.kt b/backend.native/tests/external/codegen/blackbox/coroutines/tryFinallyWithHandleResult.kt new file mode 100644 index 00000000000..c539516da92 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/tryFinallyWithHandleResult.kt @@ -0,0 +1,98 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +var globalResult = "" +var wasCalled = false +class Controller { + val postponedActions = mutableListOf<() -> Unit>() + + suspend fun suspendWithValue(v: String): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + postponedActions.add { + x.resume(v) + } + + CoroutineIntrinsics.SUSPENDED + } + + suspend fun suspendWithException(e: Exception): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + postponedActions.add { + x.resumeWithException(e) + } + + CoroutineIntrinsics.SUSPENDED + } + + fun run(c: suspend Controller.() -> String) { + c.startCoroutine(this, handleResultContinuation { + globalResult = it + }) + while (postponedActions.isNotEmpty()) { + postponedActions[0]() + postponedActions.removeAt(0) + } + } +} + +fun builder(expectException: Boolean = false, c: suspend Controller.() -> String) { + val controller = Controller() + + globalResult = "#" + wasCalled = false + if (!expectException) { + controller.run(c) + } + else { + try { + controller.run(c) + globalResult = "fail: exception was not thrown" + } catch (e: Exception) { + globalResult = e.message!! + } + } + + if (!wasCalled) { + throw RuntimeException("fail wasCalled") + } + + if (globalResult != "OK") { + throw RuntimeException("fail $globalResult") + } +} + +fun commonThrow() { + throw RuntimeException("OK") +} + +fun box(): String { + builder { + try { + suspendWithValue("OK") + } finally { + if (suspendWithValue("G") != "G") throw RuntimeException("fail 1") + wasCalled = true + } + } + + builder(expectException = true) { + try { + suspendWithException(RuntimeException("OK")) + } finally { + if (suspendWithValue("G") != "G") throw RuntimeException("fail 2") + wasCalled = true + } + } + + builder(expectException = true) { + try { + suspendWithValue("OK") + commonThrow() + suspendWithValue("OK") + } finally { + if (suspendWithValue("G") != "G") throw RuntimeException("fail 3") + wasCalled = true + } + } + + return globalResult +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/unitTypeReturn/coroutineNonLocalReturn.kt b/backend.native/tests/external/codegen/blackbox/coroutines/unitTypeReturn/coroutineNonLocalReturn.kt new file mode 100644 index 00000000000..0f462b8a2fe --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/unitTypeReturn/coroutineNonLocalReturn.kt @@ -0,0 +1,46 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume("OK") + CoroutineIntrinsics.SUSPENDED +} + +fun builder(c: suspend () -> Unit) { + var wasResumeCalled = false + c.startCoroutine(object : Continuation { + override fun resume(value: Unit) { + wasResumeCalled = true + } + + override fun resumeWithException(exception: Throwable) { + + } + }) + + if (!wasResumeCalled) throw RuntimeException("fail 1") +} + +fun box(): String { + var result = "" + + builder { + run { + if (result == "") return@builder + } + suspendHere() + throw RuntimeException("fail 2") + } + + result = "fail1" + + builder { + run { + if (result == "") return@builder + } + result = suspendHere() + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/unitTypeReturn/coroutineReturn.kt b/backend.native/tests/external/codegen/blackbox/coroutines/unitTypeReturn/coroutineReturn.kt new file mode 100644 index 00000000000..b237e7cf158 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/unitTypeReturn/coroutineReturn.kt @@ -0,0 +1,42 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume("OK") + CoroutineIntrinsics.SUSPENDED +} + +fun builder(c: suspend () -> Unit) { + var wasResumeCalled = false + c.startCoroutine(object : Continuation { + override fun resume(value: Unit) { + wasResumeCalled = true + } + + override fun resumeWithException(exception: Throwable) { + + } + }) + + if (!wasResumeCalled) throw RuntimeException("fail 1") +} + +fun box(): String { + var result = "" + + builder { + if (result == "") return@builder + suspendHere() + throw RuntimeException("fail 2") + } + + result = "fail" + + builder { + if (result == "") return@builder + result = suspendHere() + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/unitTypeReturn/suspendNonLocalReturn.kt b/backend.native/tests/external/codegen/blackbox/coroutines/unitTypeReturn/suspendNonLocalReturn.kt new file mode 100644 index 00000000000..965a1f6db93 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/unitTypeReturn/suspendNonLocalReturn.kt @@ -0,0 +1,34 @@ +// WITH_RUNTIME +// WITH_COROUTINES +// IGNORE_BACKEND: JS, NATIVE +import kotlin.coroutines.* + +var result = "0" + + +suspend fun suspendHere(x: Int): Unit { + run { + if (x == 0) return + if (x == 1) return@suspendHere + } + + result = "OK" + return CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(Unit) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +fun box(): String { + builder { + if (suspendHere(0) != Unit) throw RuntimeException("fail 1") + if (suspendHere(1) != Unit) throw RuntimeException("fail 2") + if (suspendHere(2) != Unit) throw RuntimeException("fail 3") + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/unitTypeReturn/suspendReturn.kt b/backend.native/tests/external/codegen/blackbox/coroutines/unitTypeReturn/suspendReturn.kt new file mode 100644 index 00000000000..589be86c2eb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/unitTypeReturn/suspendReturn.kt @@ -0,0 +1,27 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +var result = "0" + +suspend fun suspendHere(x: Int): Unit { + if (x == 0) return + result = "OK" + return CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume(Unit) + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +fun box(): String { + builder { + suspendHere(0) + suspendHere(1) + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/varValueConflictsWithTable.kt b/backend.native/tests/external/codegen/blackbox/coroutines/varValueConflictsWithTable.kt new file mode 100644 index 00000000000..a0c7415d6aa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/varValueConflictsWithTable.kt @@ -0,0 +1,41 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume("OK") + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +fun box(): String { + var result = "fail 1" + builder { + // Initialize var with Int value + for (i in 1..1) { + if (i != 1) continue + } + + // This variable should take the same slot as 'i' had + var s: String + + // We should not spill 's' to continuation field because it's not initialized + // More precisely it contains a value of wrong type (it conflicts with contents of local var table), + // so an attempt of spilling may lead to problems on Android + if (suspendHere() == "OK") { + s = "OK" + } + else { + s = "fail 2" + } + + result = s + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/coroutines/varValueConflictsWithTableSameSort.kt b/backend.native/tests/external/codegen/blackbox/coroutines/varValueConflictsWithTableSameSort.kt new file mode 100644 index 00000000000..d0eb7032a76 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/coroutines/varValueConflictsWithTableSameSort.kt @@ -0,0 +1,41 @@ +// WITH_RUNTIME +// WITH_COROUTINES +import kotlin.coroutines.* + +class Controller { + suspend fun suspendHere(): String = CoroutineIntrinsics.suspendCoroutineOrReturn { x -> + x.resume("OK") + CoroutineIntrinsics.SUSPENDED + } +} + +fun builder(c: suspend Controller.() -> Unit) { + c.startCoroutine(Controller(), EmptyContinuation) +} + +fun box(): String { + var result = "fail 1" + builder { + // Initialize var with Int value + try { + var i: String = "abc" + i = "123" + } finally { } + + // This variable should take the same slot as 'i' had + var s: String + + // We shout not spill 's' to continuation field because it's not effectively initialized + // But we do this because it's not illegal (at least in Android/OpenJDK VM's) + if (suspendHere() == "OK") { + s = "OK" + } + else { + s = "fail 2" + } + + result = s + } + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/arrayParams.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/arrayParams.kt new file mode 100644 index 00000000000..3c55fb1a0dd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/arrayParams.kt @@ -0,0 +1,10 @@ +data class A(val x: Array, val y: IntArray) + +fun foo(x: Array, y: IntArray) = A(x, y) + +fun box(): String { + val a = Array(0, {0}) + val b = IntArray(0) + val (x, y) = foo(a, b) + return if (a == x && b == y) "OK" else "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/changingVarParam.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/changingVarParam.kt new file mode 100644 index 00000000000..56f9c63561f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/changingVarParam.kt @@ -0,0 +1,8 @@ +data class A(var string: String) + +fun box(): String { + val a = A("Fail") + a.string = "OK" + val (result) = a + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/copy/constructorWithDefaultParam.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/copy/constructorWithDefaultParam.kt new file mode 100644 index 00000000000..5211d6889ae --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/copy/constructorWithDefaultParam.kt @@ -0,0 +1,29 @@ +data class A(val a: Int = 1, val b: String = "$a") {} + +fun box() : String { + var result = "" + val a = A() + val b = a.copy() + if (b.a == 1 && b.b == "1") { + result += "1" + } + + val c = a.copy(a = 2) + if (c.a == 2 && c.b == "1") { + result += "2" + } + + val d = a.copy(b = "2") + if (d.a == 1 && d.b == "2") { + result += "3" + } + + val e = a.copy(a = 2, b = "2") + if (e.a == 2 && e.b == "2") { + result += "4" + } + if (result == "1234") { + return "OK" + } + return "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/copy/copyInObjectNestedDataClass.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/copy/copyInObjectNestedDataClass.kt new file mode 100644 index 00000000000..935389c50cb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/copy/copyInObjectNestedDataClass.kt @@ -0,0 +1,17 @@ +class Bar(val name: String) + +abstract class Foo { + public abstract fun foo(): String +} + +fun box(): String { + return object: Foo() { + inner class NestedFoo(val bar: Bar) { + fun copy(bar: Bar) = NestedFoo(bar) + } + + override fun foo(): String { + return NestedFoo(Bar("Fail")).copy(bar = Bar("OK")).bar.name + } + }.foo() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/copy/kt12708.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/copy/kt12708.kt new file mode 100644 index 00000000000..f2ac4b4e0af --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/copy/kt12708.kt @@ -0,0 +1,13 @@ +fun box(): String { + val a: A = B(1) + a.copy(1) + a.component1() + return "OK" +} + +interface A { + fun copy(x: Int): A + fun component1(): Any +} + +data class B(val x: Int) : A diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/copy/kt3033.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/copy/kt3033.kt new file mode 100644 index 00000000000..7fc12756d88 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/copy/kt3033.kt @@ -0,0 +1,10 @@ +data class A(val a: Double, val b: Double) + +fun box() : String { + val a = A(1.0, 1.0) + val b = a.copy() + if (b.a == 1.0 && b.b == 1.0) { + return "OK" + } + return "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/copy/valInConstructorParams.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/copy/valInConstructorParams.kt new file mode 100644 index 00000000000..a340685014e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/copy/valInConstructorParams.kt @@ -0,0 +1,29 @@ +data class A(val a: Int, val b: String) {} + +fun box() : String { + var result = "" + val a = A(1, "a") + val b = a.copy() + if (b.a == 1 && b.b == "a") { + result += "1" + } + + val c = a.copy(a = 2) + if (c.a == 2 && c.b == "a") { + result += "2" + } + + val d = a.copy(b = "b") + if (d.a == 1 && d.b == "b") { + result += "3" + } + + val e = a.copy(a = 2, b = "b") + if (e.a == 2 && e.b == "b") { + result += "4" + } + if (result == "1234") { + return "OK" + } + return "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/copy/varInConstructorParams.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/copy/varInConstructorParams.kt new file mode 100644 index 00000000000..6cd1a25ae2c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/copy/varInConstructorParams.kt @@ -0,0 +1,29 @@ +data class A(var a: Int, var b: String) {} + +fun box() : String { + var result = "" + val a = A(1, "a") + val b = a.copy() + if (b.a == 1 && b.b == "a") { + result += "1" + } + + val c = a.copy(a = 2) + if (c.a == 2 && c.b == "a") { + result += "2" + } + + val d = a.copy(b = "b") + if (d.a == 1 && d.b == "b") { + result += "3" + } + + val e = a.copy(a = 2, b = "b") + if (e.a == 2 && e.b == "b") { + result += "4" + } + if (result == "1234") { + return "OK" + } + return "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/copy/withGenericParameter.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/copy/withGenericParameter.kt new file mode 100644 index 00000000000..83a4d82db02 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/copy/withGenericParameter.kt @@ -0,0 +1,14 @@ +data class A(val a: Foo) {} + +class Foo(val a: T) { } + +fun box() : String { + val f1 = Foo("a") + val f2 = Foo("b") + val a = A(f1) + val b = a.copy(f2) + if (b.a.a == "b") { + return "OK" + } + return "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/doubleParam.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/doubleParam.kt new file mode 100644 index 00000000000..50a6d8e2755 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/doubleParam.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +val NAN = Double.NaN + +data class A(val x: Double) + +fun box(): String { + if (A(+0.0) == A(-0.0)) return "Fail: +0.0 == -0.0" + if (A(+0.0).hashCode() == A(-0.0).hashCode()) return "Fail: hash(+0.0) == hash(-0.0)" + + if (A(NAN) != A(NAN)) return "Fail: NaN != NaN" + if (A(NAN).hashCode() != A(NAN).hashCode()) return "Fail: hash(NaN) != hash(NaN)" + + val s = HashSet() + for (times in 1..5) { + s.add(A(3.14)) + s.add(A(+0.0)) + s.add(A(-0.0)) + s.add(A(-2.72)) + s.add(A(NAN)) + } + + if (A(3.14) !in s) return "Fail: 3.14 not found" + if (A(+0.0) !in s) return "Fail: +0.0 not found" + if (A(-0.0) !in s) return "Fail: -0.0 not found" + if (A(-2.72) !in s) return "Fail: -2.72 not found" + if (A(NAN) !in s) return "Fail: NaN not found" + + return if (s.size == 5) "OK" else "Fail $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/equals/alreadyDeclared.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/equals/alreadyDeclared.kt new file mode 100644 index 00000000000..65e9e5b9bcf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/equals/alreadyDeclared.kt @@ -0,0 +1,8 @@ +data class A(val x: Int) { + override fun equals(other: Any?): Boolean = false +} + +fun box(): String { + val a = A(0) + return if (a.equals(a)) "fail" else "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/equals/alreadyDeclaredWrongSignature.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/equals/alreadyDeclaredWrongSignature.kt new file mode 100644 index 00000000000..8fc5ee1e118 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/equals/alreadyDeclaredWrongSignature.kt @@ -0,0 +1,37 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +data class B(val x: Int) { + fun equals(other: B): Boolean = false +} + +data class C(val x: Int) { + fun equals(): Boolean = false +} + +data class D(val x: Int) { + fun equals(other: Any?, another: String): Boolean = false +} + +data class E(val x: Int) { + fun equals(x: E): Boolean = false + override fun equals(x: Any?): Boolean = false +} + +fun box(): String { + B::class.java.getDeclaredMethod("equals", Any::class.java) + B::class.java.getDeclaredMethod("equals", B::class.java) + + C::class.java.getDeclaredMethod("equals", Any::class.java) + C::class.java.getDeclaredMethod("equals") + + D::class.java.getDeclaredMethod("equals", Any::class.java) + D::class.java.getDeclaredMethod("equals", Any::class.java, String::class.java) + + E::class.java.getDeclaredMethod("equals", Any::class.java) + E::class.java.getDeclaredMethod("equals", E::class.java) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/equals/genericarray.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/equals/genericarray.kt new file mode 100644 index 00000000000..eaf4b04032e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/equals/genericarray.kt @@ -0,0 +1,8 @@ +data class A(val v: Array) + +fun box() : String { + val myArray = arrayOf(0, 1, 2) + if(A(myArray) == A(arrayOf(0, 1, 2))) return "fail" + if(A(myArray) != A(myArray)) return "fail 2" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/equals/intarray.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/equals/intarray.kt new file mode 100644 index 00000000000..85eb1bec509 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/equals/intarray.kt @@ -0,0 +1,8 @@ +data class A(val v: IntArray) + +fun box() : String { + val myArray = intArrayOf(0, 1, 2) + if(A(myArray) == A(intArrayOf(0, 1, 2))) return "fail" + if(A(myArray) != A(myArray)) return "fail 2" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/equals/nullother.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/equals/nullother.kt new file mode 100644 index 00000000000..bb0f764e061 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/equals/nullother.kt @@ -0,0 +1,11 @@ +class Dummy { + override fun equals(other: Any?) = true +} + +data class A(val v: Any?) + +fun box() : String { + val a = A(Dummy()) + val b: A? = null + return if(a != b && b != a) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/equals/sameinstance.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/equals/sameinstance.kt new file mode 100644 index 00000000000..04a1cfdc4f1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/equals/sameinstance.kt @@ -0,0 +1,7 @@ +data class A(val arg: Any? = null) + +fun box() : String { + val a = A() + val b = a + return if(b == a) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/floatParam.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/floatParam.kt new file mode 100644 index 00000000000..f6e2224ba71 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/floatParam.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +val NAN = Float.NaN + +data class A(val x: Float) + +fun box(): String { + if (A(+0f) == A(-0f)) return "Fail: +0 == -0" + if (A(+0f).hashCode() == A(-0f).hashCode()) return "Fail: hash(+0) == hash(-0)" + + if (A(NAN) != A(NAN)) return "Fail: NaN != NaN" + if (A(NAN).hashCode() != A(NAN).hashCode()) return "Fail: hash(NaN) != hash(NaN)" + + val s = HashSet() + for (times in 1..5) { + s.add(A(3.14f)) + s.add(A(+0f)) + s.add(A(-0f)) + s.add(A(-2.72f)) + s.add(A(NAN)) + } + + if (A(3.14f) !in s) return "Fail: 3.14 not found" + if (A(+0f) !in s) return "Fail: +0 not found" + if (A(-0f) !in s) return "Fail: -0 not found" + if (A(-2.72f) !in s) return "Fail: -2.72 not found" + if (A(NAN) !in s) return "Fail: NaN not found" + + return if (s.size == 5) "OK" else "Fail $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/genericParam.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/genericParam.kt new file mode 100644 index 00000000000..5bf58f528f7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/genericParam.kt @@ -0,0 +1,12 @@ +data class A(val x: T) + +fun box(): String { + val a = A(42) + if (a.component1() != 42) return "Fail a: ${a.component1()}" + + val b = A(239.toLong()) + if (b.component1() != 239.toLong()) return "Fail b: ${b.component1()}" + + val c = A("OK") + return c.component1() +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/alreadyDeclared.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/alreadyDeclared.kt new file mode 100644 index 00000000000..ee7b621c974 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/alreadyDeclared.kt @@ -0,0 +1,7 @@ +data class A(val x: Int) { + override fun hashCode(): Int = -3 +} + +fun box(): String { + return if (A(0).hashCode() == -3) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/alreadyDeclaredWrongSignature.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/alreadyDeclaredWrongSignature.kt new file mode 100644 index 00000000000..254e1b93220 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/alreadyDeclaredWrongSignature.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +data class A(val x: Int) { + fun hashCode(other: Any): Int = 0 +} + +data class B(val x: Int) { + fun hashCode(other: B, another: Any): Int = 0 +} + +fun box(): String { + A::class.java.getDeclaredMethod("hashCode") + A::class.java.getDeclaredMethod("hashCode", Any::class.java) + + B::class.java.getDeclaredMethod("hashCode") + B::class.java.getDeclaredMethod("hashCode", B::class.java, Any::class.java) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/array.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/array.kt new file mode 100644 index 00000000000..083fde96ce0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/array.kt @@ -0,0 +1,9 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +data class A(val a: IntArray, var b: Array) + +fun box() : String { + if( A(intArrayOf(1,2,3),arrayOf("239")).hashCode() != 31*java.util.Arrays.hashCode(intArrayOf(0,1,2)) + "239".hashCode()) "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/boolean.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/boolean.kt new file mode 100644 index 00000000000..afc41bbe2e7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/boolean.kt @@ -0,0 +1,5 @@ +data class A(val a: Boolean) + +fun box() : String { + return if( A(true).hashCode()==1 && A(false).hashCode()==0 ) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/byte.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/byte.kt new file mode 100644 index 00000000000..ce33977b555 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/byte.kt @@ -0,0 +1,7 @@ +data class A(val a: Byte) + +fun box() : String { + val v1 = A(10.toByte()).hashCode() + val v2 = (10.toByte() as Byte?)!!.hashCode() + return if( v1 == v2 ) "OK" else "$v1 $v2" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/char.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/char.kt new file mode 100644 index 00000000000..e2ac5e67291 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/char.kt @@ -0,0 +1,7 @@ +data class A(val a: Char) + +fun box() : String { + val v1 = A('a').hashCode() + val v2 = ('a' as Char?)!!.hashCode() + return if( v1 == v2 ) "OK" else "$v1 $v2" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/double.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/double.kt new file mode 100644 index 00000000000..f0899ad1b59 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/double.kt @@ -0,0 +1,7 @@ +data class A(val a: Double) + +fun box() : String { + val v1 = A(-10.toDouble()).hashCode() + val v2 = (-10.toDouble() as Double?)!!.hashCode() + return if( v1 == v2 ) "OK" else "$v1 $v2" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/float.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/float.kt new file mode 100644 index 00000000000..41dc25c43c4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/float.kt @@ -0,0 +1,7 @@ +data class A(val a: Float) + +fun box() : String { + val v1 = A(-10.toFloat()).hashCode() + val v2 = (-10.toFloat() as Float?)!!.hashCode() + return if( v1 == v2 ) "OK" else "$v1 $v2" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/genericNull.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/genericNull.kt new file mode 100644 index 00000000000..6987eab9670 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/genericNull.kt @@ -0,0 +1,7 @@ +data class A(val t: T) + +fun box(): String { + val h = A(null).hashCode() + if (h != 0) return "Fail $h" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/int.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/int.kt new file mode 100644 index 00000000000..0596e4c72af --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/int.kt @@ -0,0 +1,7 @@ +data class A(val a: Int) + +fun box() : String { + val v1 = A(-10.toInt()).hashCode() + val v2 = (-10.toInt() as Int?)!!.hashCode() + return if( v1 == v2 ) "OK" else "$v1 $v2" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/long.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/long.kt new file mode 100644 index 00000000000..067593cb672 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/long.kt @@ -0,0 +1,7 @@ +data class A(val a: Long) + +fun box() : String { + val v1 = A(-10.toLong()).hashCode() + val v2 = (-10.toLong() as Long?)!!.hashCode() + return if( v1 == v2 ) "OK" else "$v1 $v2" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/null.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/null.kt new file mode 100644 index 00000000000..75777abec50 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/null.kt @@ -0,0 +1,16 @@ +data class A(val a: Any?, var x: Int) +data class B(val a: Any?) +data class C(val a: Int, var x: Int?) +data class D(val a: Int?) + +fun box() : String { + if( A(null,19).hashCode() != 19) "fail" + if( A(239,19).hashCode() != (239*31+19)) "fail" + if( B(null).hashCode() != 0) "fail" + if( B(239).hashCode() != 239) "fail" + if( C(239,19).hashCode() != (239*31+19)) "fail" + if( C(239,null).hashCode() != 239*31) "fail" + if( D(239).hashCode() != (239)) "fail" + if( D(null).hashCode() != 0) "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/short.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/short.kt new file mode 100644 index 00000000000..5e220e27cfc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/hashCode/short.kt @@ -0,0 +1,7 @@ +data class A(val a: Short) + +fun box() : String { + val v1 = A(10.toShort()).hashCode() + val v2 = (10.toShort() as Short?)!!.hashCode() + return if( v1 == v2 ) "OK" else "$v1 $v2" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/kt5002.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/kt5002.kt new file mode 100644 index 00000000000..d624ca5b93c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/kt5002.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +import java.io.Serializable + +public data class Pair ( + public val first: A, + public val second: B +) : Serializable + +fun box(): String { + val p = Pair(42, "OK") + val q = Pair(42, "OK") + if (p != q) return "Fail equals" + if (p.hashCode() != q.hashCode()) return "Fail hashCode" + if (p.toString() != q.toString()) return "Fail toString" + return p.second +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/mixedParams.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/mixedParams.kt new file mode 100644 index 00000000000..90637df9768 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/mixedParams.kt @@ -0,0 +1,8 @@ +data class A(var x: Int, val z: Int) + +fun box(): String { + val a = A(1, 3) + if (a.component1() != 1) return "Fail: ${a.component1()}" + if (a.component2() != 3) return "Fail: ${a.component2()}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/multiDeclaration.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/multiDeclaration.kt new file mode 100644 index 00000000000..c74ea42a4a3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/multiDeclaration.kt @@ -0,0 +1,7 @@ +data class A(val x: Int, val y: Any?, val z: String) + +fun box(): String { + val a = A(42, null, "OK") + val (x, y, z) = a + return if (x == 42 && y == null) z else "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/multiDeclarationFor.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/multiDeclarationFor.kt new file mode 100644 index 00000000000..b7756b0c036 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/multiDeclarationFor.kt @@ -0,0 +1,17 @@ +data class A(val x: Int, val y: String) + +fun box(): String { + val arr = Array(5) { + i -> A(i, i.toString()) + } + + var sum = 0 + var str = "" + + for ((x, y) in arr) { + sum += x + str += y + } + + return if (sum == 0+1+2+3+4 && str == "01234") "OK" else "Fail ${sum} ${str}" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/nonTrivialFinalMemberInSuperClass.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/nonTrivialFinalMemberInSuperClass.kt new file mode 100644 index 00000000000..4e655f2d38e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/nonTrivialFinalMemberInSuperClass.kt @@ -0,0 +1,17 @@ +abstract class Base { + final override fun toString() = "OK" + final override fun hashCode() = 42 + final override fun equals(other: Any?) = false +} + +data class DataClass(val field: String) : Base() + +fun box(): String { + val d = DataClass("x") + + if (d.toString() != "OK") return "Fail toString" + if (d.hashCode() != 42) return "Fail hashCode" + if (d.equals(d) != false) return "Fail equals" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/nonTrivialMemberInSuperClass.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/nonTrivialMemberInSuperClass.kt new file mode 100644 index 00000000000..32287fbd597 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/nonTrivialMemberInSuperClass.kt @@ -0,0 +1,19 @@ +// See KT-6206 Always generate hashCode() and equals() for data classes even if base classes have non-trivial analogs + +abstract class Base { + override fun toString() = "Fail" + override fun hashCode() = -42 + override fun equals(other: Any?) = false +} + +data class DataClass(val field: String) : Base() + +fun box(): String { + val d = DataClass("x") + + if (d.toString() != "DataClass(field=x)") return "Fail toString" + if (d.hashCode() != "x".hashCode()) return "Fail hashCode" + if (d.equals(d) == false) return "Fail equals" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/privateValParams.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/privateValParams.kt new file mode 100644 index 00000000000..d667588ab98 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/privateValParams.kt @@ -0,0 +1,13 @@ +data class D(private val x: Long, private val y: Char) { + fun foo() = "${component1()}${component2()}" +} + +fun box(): String { + val d1 = D(42L, 'a') + val d2 = D(42L, 'a') + if (d1 != d2) return "Fail equals" + if (d1.hashCode() != d2.hashCode()) return "Fail hashCode" + if (d1.toString() != d2.toString()) return "Fail toString" + if (d1.foo() != d2.foo()) return "Fail foo" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/toString/alreadyDeclared.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/toString/alreadyDeclared.kt new file mode 100644 index 00000000000..f95ea92633c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/toString/alreadyDeclared.kt @@ -0,0 +1,7 @@ +data class A(val x: Int) { + override fun toString(): String = "!" +} + +fun box(): String { + return if (A(0).toString() == "!") "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/toString/alreadyDeclaredWrongSignature.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/toString/alreadyDeclaredWrongSignature.kt new file mode 100644 index 00000000000..e343bb06260 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/toString/alreadyDeclaredWrongSignature.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +data class A(val x: Int) { + fun toString(other: Any): String = "" +} + +data class B(val x: Int) { + fun toString(other: B, another: Any): String = "" +} + +fun box(): String { + A::class.java.getDeclaredMethod("toString") + A::class.java.getDeclaredMethod("toString", Any::class.java) + + B::class.java.getDeclaredMethod("toString") + B::class.java.getDeclaredMethod("toString", B::class.java, Any::class.java) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/toString/arrayParams.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/toString/arrayParams.kt new file mode 100644 index 00000000000..9292bc9341b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/toString/arrayParams.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +data class A(val x: Array?, val y: IntArray?) + +fun box(): String { + var ts = A(Array(2, {it}), IntArray(3)).toString() + if(ts != "A(x=[0, 1], y=[0, 0, 0])") return ts + + ts = A(null, IntArray(3)).toString() + if(ts != "A(x=null, y=[0, 0, 0])") return ts + + ts = A(null, null).toString() + if(ts != "A(x=null, y=null)") return ts + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/toString/changingVarParam.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/toString/changingVarParam.kt new file mode 100644 index 00000000000..0268af29435 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/toString/changingVarParam.kt @@ -0,0 +1,11 @@ +data class A(var string: String) + +fun box(): String { + val a = A("Fail") + if(a.toString() != "A(string=Fail)") return "fail" + + a.string = "OK" + if("$a" != "A(string=OK)") return a.toString() + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/toString/genericParam.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/toString/genericParam.kt new file mode 100644 index 00000000000..794bad5dbe1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/toString/genericParam.kt @@ -0,0 +1,11 @@ +data class A(val x: T) + +fun box(): String { + val a = A(42) + if ("$a" != "A(x=42)") return "$a" + + val b = A(239.toLong()) + if ("$b" != "A(x=239)") return "$b" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/toString/mixedParams.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/toString/mixedParams.kt new file mode 100644 index 00000000000..a8e9b7dbd20 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/toString/mixedParams.kt @@ -0,0 +1,7 @@ +data class A(var x: Int, val z: Int?) + +fun box(): String { + val a = A(1, null) + if("$a" != "A(x=1, z=null)") return "$a" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/toString/unitComponent.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/toString/unitComponent.kt new file mode 100644 index 00000000000..72e5965b320 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/toString/unitComponent.kt @@ -0,0 +1,6 @@ +data class A(val x: Unit) + +fun box(): String { + val a = A(Unit) + return if ("$a" == "A(x=kotlin.Unit)") "OK" else "$a" +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/twoValParams.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/twoValParams.kt new file mode 100644 index 00000000000..91b918b1a8c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/twoValParams.kt @@ -0,0 +1,6 @@ +data class A(val x: Int, val y: String) + +fun box(): String { + val a = A(42, "OK") + return if (a.component1() == 42) a.component2() else a.component1().toString() +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/twoVarParams.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/twoVarParams.kt new file mode 100644 index 00000000000..053cfe55892 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/twoVarParams.kt @@ -0,0 +1,9 @@ +data class A(var x: Int, var y: String) + +fun box(): String { + val a = A(21, "K") + if (a.component1() != 21 || a.component2() != "K") return "Fail" + a.x *= 2 + a.y = "O" + a.component2() + return if (a.component1() == 42) a.component2() else a.component1().toString() +} diff --git a/backend.native/tests/external/codegen/blackbox/dataClasses/unitComponent.kt b/backend.native/tests/external/codegen/blackbox/dataClasses/unitComponent.kt new file mode 100644 index 00000000000..b70b461ab91 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/dataClasses/unitComponent.kt @@ -0,0 +1,6 @@ +data class A(val x: Unit) + +fun box(): String { + val a = A(Unit) + return if (a.component1() is Unit) "OK" else "Fail ${a.component1()}" +} diff --git a/backend.native/tests/external/codegen/blackbox/deadCodeElimination/emptyVariableRange.kt b/backend.native/tests/external/codegen/blackbox/deadCodeElimination/emptyVariableRange.kt new file mode 100644 index 00000000000..c162fbeec34 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/deadCodeElimination/emptyVariableRange.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun foo(): Int { + return 1 + // val xyz has empty live range because everything after return will be removed as dead + val xyz = 1 +} + +fun box(): String { + assertEquals(1, foo()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/deadCodeElimination/intersectingVariableRange.kt b/backend.native/tests/external/codegen/blackbox/deadCodeElimination/intersectingVariableRange.kt new file mode 100644 index 00000000000..4d685fb2a0c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/deadCodeElimination/intersectingVariableRange.kt @@ -0,0 +1,13 @@ +fun box(): String { + try { + return "OK" + if (1 == 1) { + val z = 2 + } + if (3 == 3) { + val z = 4 + } + } finally { + + } +} diff --git a/backend.native/tests/external/codegen/blackbox/deadCodeElimination/intersectingVariableRangeInFinally.kt b/backend.native/tests/external/codegen/blackbox/deadCodeElimination/intersectingVariableRangeInFinally.kt new file mode 100644 index 00000000000..071bd50aa47 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/deadCodeElimination/intersectingVariableRangeInFinally.kt @@ -0,0 +1,12 @@ +fun box(): String { + try { + return "OK" + } finally { + if (1 == 1) { + val z = 2 + } + if (3 == 3) { + val z = 4 + } + } +} diff --git a/backend.native/tests/external/codegen/blackbox/deadCodeElimination/kt14357.kt b/backend.native/tests/external/codegen/blackbox/deadCodeElimination/kt14357.kt new file mode 100644 index 00000000000..377a6facdac --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/deadCodeElimination/kt14357.kt @@ -0,0 +1,10 @@ +fun box(): String { + if (false) { + try { + null!! + } catch (e: Exception) { + throw e + } + } + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/annotation.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/annotation.kt new file mode 100644 index 00000000000..f7e1453599d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/annotation.kt @@ -0,0 +1,11 @@ +annotation class A(val a: Int = 0) + +@A fun test1() = 1 +@A(2) fun test2() = 1 + +fun box(): String { + if ((test1() + test2()) == 2) { + return "OK" + } + return "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/checkIfConstructorIsSynthetic.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/checkIfConstructorIsSynthetic.kt new file mode 100644 index 00000000000..cfd12c58f64 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/checkIfConstructorIsSynthetic.kt @@ -0,0 +1,11 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class A(value: Int = 1) + +fun box(): String { + val constructors = A::class.java.getConstructors().filter { !it.isSynthetic() } + return if (constructors.size == 2) "OK" else constructors.size.toString() +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/defArgs1.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/defArgs1.kt new file mode 100644 index 00000000000..db8161f1911 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/defArgs1.kt @@ -0,0 +1,8 @@ +class A(val a: Int = 0) + +fun box(): String { + if (A().a == 0 && A(1).a == 1) { + return "OK" + } + return "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/defArgs1InnerClass.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/defArgs1InnerClass.kt new file mode 100644 index 00000000000..588b0cf1c60 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/defArgs1InnerClass.kt @@ -0,0 +1,14 @@ +class A { + inner class B(val a: String = "a", val b: Int = 55, val c: String = "c") +} + +fun box(): String { + val bDefault = A().B() + val b = A().B("aa", 66, "cc") + if (bDefault.a == "a" && bDefault.b == 55 && bDefault.c == "c") { + if (b.a == "aa" && b.b == 66 && b.c == "cc") { + return "OK" + } + } + return "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/defArgs2.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/defArgs2.kt new file mode 100644 index 00000000000..9a22d318336 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/defArgs2.kt @@ -0,0 +1,13 @@ +class A(val a: Int = 0, val b: String = "a") + +fun box(): String { + val a1 = A() + val a2 = A(1) + val a3 = A(b = "b") + val a4 = A(2, "c") + if (a1.a != 0 && a1.b != "a") return "fail" + if (a2.a != 1 && a2.b != "a") return "fail" + if (a3.a != 0 && a3.b != "b") return "fail" + if (a4.a != 2 && a4.b != "c") return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/doubleDefArgs1InnerClass.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/doubleDefArgs1InnerClass.kt new file mode 100644 index 00000000000..cc9737c3e47 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/doubleDefArgs1InnerClass.kt @@ -0,0 +1,14 @@ +class A { + inner class B(val a: Double = 1.0, val b: Int = 55, val c: String = "c") +} + +fun box(): String { + val bDefault = A().B() + val b = A().B(2.0, 66, "cc") + if (bDefault.a == 1.0 && bDefault.b == 55 && bDefault.c == "c") { + if (b.a == 2.0 && b.b == 66 && b.c == "cc") { + return "OK" + } + } + return "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/enum.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/enum.kt new file mode 100644 index 00000000000..edc9e061d4c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/enum.kt @@ -0,0 +1,11 @@ +enum class A(val a: Int = 1) { + FIRST(), + SECOND(2) +} + +fun box(): String { + if (A.FIRST.a == 1 && A.SECOND.a == 2) { + return "OK" + } + return "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/enumWithOneDefArg.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/enumWithOneDefArg.kt new file mode 100644 index 00000000000..339ab868c0d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/enumWithOneDefArg.kt @@ -0,0 +1,10 @@ +enum class Foo(val a: Int = 1, val b: String) { + B(2, "b"), + C(b = "b") +} + +fun box(): String { + if (Foo.B.a != 2 || Foo.B.b != "b") return "fail" + if (Foo.C.a != 1 || Foo.C.b != "b") return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/enumWithTwoDefArgs.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/enumWithTwoDefArgs.kt new file mode 100644 index 00000000000..7a7d6db0814 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/enumWithTwoDefArgs.kt @@ -0,0 +1,14 @@ +enum class Foo(val a: Int = 1, val b: String = "a") { + A(), + B(2, "b"), + C(b = "b"), + D(a = 2) +} + +fun box(): String { + if (Foo.A.a != 1 || Foo.A.b != "a") return "fail" + if (Foo.B.a != 2 || Foo.B.b != "b") return "fail" + if (Foo.C.a != 1 || Foo.C.b != "b") return "fail" + if (Foo.D.a != 2 || Foo.D.b != "a") return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/enumWithTwoDoubleDefArgs.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/enumWithTwoDoubleDefArgs.kt new file mode 100644 index 00000000000..e461fd6a32e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/enumWithTwoDoubleDefArgs.kt @@ -0,0 +1,14 @@ +enum class Foo(val a: Double = 1.0, val b: Double = 1.0) { + A(), + B(2.0, 2.0), + C(b = 2.0), + D(a = 2.0) +} + +fun box(): String { + if (Foo.A.a != 1.0 || Foo.A.b != 1.0) return "fail" + if (Foo.B.a != 2.0 || Foo.B.b != 2.0) return "fail" + if (Foo.C.a != 1.0 || Foo.C.b != 2.0) return "fail" + if (Foo.D.a != 2.0 || Foo.D.b != 1.0) return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/kt2852.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/kt2852.kt new file mode 100644 index 00000000000..9a5434a99cf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/kt2852.kt @@ -0,0 +1,7 @@ +fun box(): String { + val o = object { + inner class A(val value: String = "OK") + } + + return o.A().value +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/kt3060.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/kt3060.kt new file mode 100644 index 00000000000..ca4275a7403 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/kt3060.kt @@ -0,0 +1,10 @@ +class Foo private constructor(val param: String = "OK") { + companion object { + val s = Foo() + } +} + +fun box(): String { + Foo.s.param + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/manyArgs.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/manyArgs.kt new file mode 100644 index 00000000000..ac3eab5136f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/constructor/manyArgs.kt @@ -0,0 +1,216 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class A(val a: Int = 1, + val b: Int = 2, + val c: Int = 3, + val d: Int = 4, + val e: Int = 5, + val f: Int = 6, + val g: Int = 7, + val h: Int = 8, + val i: Int = 9, + val j: Int = 10, + val k: Int = 11, + val l: Int = 12, + val m: Int = 13, + val n: Int = 14, + val o: Int = 15, + val p: Int = 16, + val q: Int = 17, + val r: Int = 18, + val s: Int = 19, + val t: Int = 20, + val u: Int = 21, + val v: Int = 22, + val w: Int = 23, + val x: Int = 24, + val y: Int = 25, + val z: Int = 26, + val aa: Int = 27, + val bb: Int = 28, + val cc: Int = 29, + val dd: Int = 30, + val ee: Int = 31, + val ff: Int = 32) { + override fun toString(): String { + return "$a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z $aa $bb $cc $dd $ee $ff" + } +} + +class B(val a: Int = 1, + val b: Int = 2, + val c: Int = 3, + val d: Int = 4, + val e: Int = 5, + val f: Int = 6, + val g: Int = 7, + val h: Int = 8, + val i: Int = 9, + val j: Int = 10, + val k: Int = 11, + val l: Int = 12, + val m: Int = 13, + val n: Int = 14, + val o: Int = 15, + val p: Int = 16, + val q: Int = 17, + val r: Int = 18, + val s: Int = 19, + val t: Int = 20, + val u: Int = 21, + val v: Int = 22, + val w: Int = 23, + val x: Int = 24, + val y: Int = 25, + val z: Int = 26, + val aa: Int = 27, + val bb: Int = 28, + val cc: Int = 29, + val dd: Int = 30, + val ee: Int = 31, + val ff: Int = 32, + val gg: Int = 33, + val hh: Int = 34, + val ii: Int = 35, + val jj: Int = 36, + val kk: Int = 37, + val ll: Int = 38, + val mm: Int = 39, + val nn: Int = 40) { + override fun toString(): String { + return "$a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z $aa $bb $cc $dd $ee $ff " + + "$gg $hh $ii $jj $kk $ll $mm $nn" + } +} + +class C(val a: Int = 1, + val b: Int = 2, + val c: Int = 3, + val d: Int = 4, + val e: Int = 5, + val f: Int = 6, + val g: Int = 7, + val h: Int = 8, + val i: Int = 9, + val j: Int = 10, + val k: Int = 11, + val l: Int = 12, + val m: Int = 13, + val n: Int = 14, + val o: Int = 15, + val p: Int = 16, + val q: Int = 17, + val r: Int = 18, + val s: Int = 19, + val t: Int = 20, + val u: Int = 21, + val v: Int = 22, + val w: Int = 23, + val x: Int = 24, + val y: Int = 25, + val z: Int = 26, + val aa: Int = 27, + val bb: Int = 28, + val cc: Int = 29, + val dd: Int = 30, + val ee: Int = 31, + val ff: Int = 32, + val gg: Int = 33, + val hh: Int = 34, + val ii: Int = 35, + val jj: Int = 36, + val kk: Int = 37, + val ll: Int = 38, + val mm: Int = 39, + val nn: Int = 40, + val oo: Int = 41, + val pp: Int = 42, + val qq: Int = 43, + val rr: Int = 44, + val ss: Int = 45, + val tt: Int = 46, + val uu: Int = 47, + val vv: Int = 48, + val ww: Int = 49, + val xx: Int = 50, + val yy: Int = 51, + val zz: Int = 52, + val aaa: Int = 53, + val bbb: Int = 54, + val ccc: Int = 55, + val ddd: Int = 56, + val eee: Int = 57, + val fff: Int = 58, + val ggg: Int = 59, + val hhh: Int = 60, + val iii: Int = 61, + val jjj: Int = 62, + val kkk: Int = 63, + val lll: Int = 64, + val mmm: Int = 65, + val nnn: Int = 66, + val ooo: Int = 67, + val ppp: Int = 68, + val qqq: Int = 69, + val rrr: Int = 70) { + override fun toString(): String { + return "$a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z $aa $bb $cc $dd $ee $ff $gg $hh $ii $jj $kk " + + "$ll $mm $nn $oo $pp $qq $rr $ss $tt $uu $vv $ww $xx $yy $zz $aaa $bbb $ccc $ddd $eee $fff $ggg $hhh $iii $jjj $kkk $lll " + + "$mmm $nnn $ooo $ppp $qqq $rrr" + } +} + +fun box(): String { + val test1 = A(4, e = 8, f = 15, w = 16, aa = 23, ff = 42).toString() + val test2 = A::class.java.newInstance().toString() + val test3 = A(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, q = 16, r = 15, s = 14, t = 13, + u = 12, v = 11, w = 10, x = 9, y = 8, z = 7, aa = 6, bb = 5, cc = 4, dd = 3, ee = 2, ff = 1).toString() + if (test1 != "4 2 3 4 8 15 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 16 24 25 26 23 28 29 30 31 42") { + return "test1 = $test1" + } + if (test2 != "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32") { + return "test2 = $test2" + } + if (test3 != "32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1") { + return "test3 = $test3" + } + + val test4 = B(54, 217, h = 236, l = 18, q = 3216, u = 8, aa = 22, ff = 33, jj = 44, mm = 55).toString() + val test5 = B::class.java.newInstance().toString() + val test6 = B(40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, u = 20, v = 19, + w = 18, x = 17, y = 16, z = 15, aa = 14, bb = 13, cc = 12, dd = 11, ee = 10, ff = 9, gg = 8, hh = 7, ii = 6, + jj = 5, kk = 4, ll = 3, mm = 2, nn = 1).toString() + if (test4 != "54 217 3 4 5 6 7 236 9 10 11 18 13 14 15 16 3216 18 19 20 8 22 23 24 25 26 22 28 29 30 31 33 33 34 35 44 37 38 55 40") { + return "test4 = $test4" + } + if (test5 != "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40") { + return "test5 = $test5" + } + if (test6 != "40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1") { + return "test6 = $test6" + } + + val test7 = C(5, f = 3, w = 1, aa = 71, nn = 2, qq = 15, ww = 97, aaa = 261258, iii = 3, nnn = 8, rrr = 7).toString() + val test8 = C::class.java.newInstance().toString() + val test9 = C(70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, + 40, 39, 38, 37, 36, jj = 35, kk = 34, ll = 33, mm = 32, nn = 31, oo = 30, pp = 29, qq = 28, rr = 27, ss = 26, tt = 25, + uu = 24, vv = 23, ww = 22, xx = 21, yy = 20, zz = 19, aaa = 18, bbb = 17, ccc = 16, ddd = 15, eee = 14, fff = 13, + ggg = 12, hhh = 11, iii = 10, jjj = 9, kkk = 8, lll = 7, mmm = 6, nnn = 5, ooo = 4, ppp = 3, qqq = 2, rrr = 1).toString() + if (test7 != "5 2 3 4 5 3 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 24 25 26 71 28 29 30 31 32 33 34 35 36 37 38 39 2 41 42 15 " + + "44 45 46 47 48 97 50 51 52 261258 54 55 56 57 58 59 60 3 62 63 64 65 8 67 68 69 7") { + return "test7 = $test7" + } + if (test8 != "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 " + + "43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70") { + return "test8 = $test8" + } + if (test9 != "70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 " + + "31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1") { + return "test9 = $test9" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/convention/incWithDefaultInGetter.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/convention/incWithDefaultInGetter.kt new file mode 100644 index 00000000000..a576bf5b852 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/convention/incWithDefaultInGetter.kt @@ -0,0 +1,26 @@ +var inc: String = "" + +class X { + var result: String = "fail" + + operator fun get(name: String, type: String = "none") = name + inc + type + + operator fun set(name: String, s: String) { + result = name + s; + } +} + +operator fun String.inc(): String { + inc = this + "1" + return this + "1" +} + +fun box(): String { + var x = X() + val res = ++x["a"] + if (x.result != "aanone1") return "fail 1: ${x.result}" + + if (res != "aanone1none") return "fail 2: ${res}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/convention/kt9140.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/convention/kt9140.kt new file mode 100644 index 00000000000..ea677b74a84 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/convention/kt9140.kt @@ -0,0 +1,11 @@ +class X { + operator fun get(name: String, type: String = "none") = name + type +} + +fun box(): String { + if (X().get("a") != "anone") return "fail 1: ${X().get("a")}" + + if (X()["a"] != "anone") return "fail 2: ${X()["a"]}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/convention/plusAssignWithDefaultInGetter.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/convention/plusAssignWithDefaultInGetter.kt new file mode 100644 index 00000000000..0b6f63450de --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/convention/plusAssignWithDefaultInGetter.kt @@ -0,0 +1,31 @@ +class X { + var result: String = "fail" + + operator fun get(name: String, type: String = "none") = name + type + + operator fun set(name: String, s: String) { + result = name + s; + } +} + +class Y { + var result: String = "fail" + + operator fun get(name: String, type: String = "no", type2: String = "ne") = name + type + type2 + + operator fun set(name: String, s: String) { + result = name + s; + } +} + +fun box(): String { + var x = X() + x["a"] += "OK" + if (x.result != "aanoneOK") return "fail: ${x.result}" + + var y = Y() + y["a"] += "OK" + if (y.result != "aanoneOK") return "fail: ${y.result}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/abstractClass.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/abstractClass.kt new file mode 100644 index 00000000000..c1cc5d0bd9e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/abstractClass.kt @@ -0,0 +1,16 @@ +abstract class Base { + abstract fun foo(a: String = "abc"): String +} + +class Derived: Base() { + override fun foo(a: String): String { + return a + } +} + +fun box(): String { + val result = Derived().foo() + if (result != "abc") return "Fail: $result" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/covariantOverride.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/covariantOverride.kt new file mode 100644 index 00000000000..b2ad3e749c2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/covariantOverride.kt @@ -0,0 +1,10 @@ +open class Foo { + open fun foo(x: CharSequence = "O"): CharSequence = x +} +class Bar(): Foo() { + override fun foo(x: CharSequence): String { // Note the covariant return type + return x.toString() + "K" + } +} + +fun box() = Bar().foo() diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/covariantOverrideGeneric.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/covariantOverrideGeneric.kt new file mode 100644 index 00000000000..9f24919d51d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/covariantOverrideGeneric.kt @@ -0,0 +1,10 @@ +open class Foo { + open fun foo(x: CharSequence = "O"): CharSequence = x +} +class Bar: Foo() { + override fun foo(x: CharSequence): T { // Note the covariant return type + return (x.toString() + "K") as T + } +} + +fun box() = Bar().foo() diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extensionFunctionManyArgs.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extensionFunctionManyArgs.kt new file mode 100644 index 00000000000..82984a99369 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extensionFunctionManyArgs.kt @@ -0,0 +1,205 @@ +fun Int.foo(a: Int = 1, + b: Int = 2, + c: Int = 3, + d: Int = 4, + e: Int = 5, + f: Int = 6, + g: Int = 7, + h: Int = 8, + i: Int = 9, + j: Int = 10, + k: Int = 11, + l: Int = 12, + m: Int = 13, + n: Int = 14, + o: Int = 15, + p: Int = 16, + q: Int = 17, + r: Int = 18, + s: Int = 19, + t: Int = 20, + u: Int = 21, + v: Int = 22, + w: Int = 23, + x: Int = 24, + y: Int = 25, + z: Int = 26, + aa: Int = 27, + bb: Int = 28, + cc: Int = 29, + dd: Int = 30, + ee: Int = 31, + ff: Int = 32): String { + return "$a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z $aa $bb $cc $dd $ee $ff" +} + +fun String.bar(a: Int = 1, + b: Int = 2, + c: Int = 3, + d: Int = 4, + e: Int = 5, + f: Int = 6, + g: Int = 7, + h: Int = 8, + i: Int = 9, + j: Int = 10, + k: Int = 11, + l: Int = 12, + m: Int = 13, + n: Int = 14, + o: Int = 15, + p: Int = 16, + q: Int = 17, + r: Int = 18, + s: Int = 19, + t: Int = 20, + u: Int = 21, + v: Int = 22, + w: Int = 23, + x: Int = 24, + y: Int = 25, + z: Int = 26, + aa: Int = 27, + bb: Int = 28, + cc: Int = 29, + dd: Int = 30, + ee: Int = 31, + ff: Int = 32, + gg: Int = 33, + hh: Int = 34, + ii: Int = 35, + jj: Int = 36, + kk: Int = 37, + ll: Int = 38, + mm: Int = 39, + nn: Int = 40): String { + return "$a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z $aa $bb $cc $dd $ee $ff " + + "$gg $hh $ii $jj $kk $ll $mm $nn" +} + +fun Char.baz(a: Int = 1, + b: Int = 2, + c: Int = 3, + d: Int = 4, + e: Int = 5, + f: Int = 6, + g: Int = 7, + h: Int = 8, + i: Int = 9, + j: Int = 10, + k: Int = 11, + l: Int = 12, + m: Int = 13, + n: Int = 14, + o: Int = 15, + p: Int = 16, + q: Int = 17, + r: Int = 18, + s: Int = 19, + t: Int = 20, + u: Int = 21, + v: Int = 22, + w: Int = 23, + x: Int = 24, + y: Int = 25, + z: Int = 26, + aa: Int = 27, + bb: Int = 28, + cc: Int = 29, + dd: Int = 30, + ee: Int = 31, + ff: Int = 32, + gg: Int = 33, + hh: Int = 34, + ii: Int = 35, + jj: Int = 36, + kk: Int = 37, + ll: Int = 38, + mm: Int = 39, + nn: Int = 40, + oo: Int = 41, + pp: Int = 42, + qq: Int = 43, + rr: Int = 44, + ss: Int = 45, + tt: Int = 46, + uu: Int = 47, + vv: Int = 48, + ww: Int = 49, + xx: Int = 50, + yy: Int = 51, + zz: Int = 52, + aaa: Int = 53, + bbb: Int = 54, + ccc: Int = 55, + ddd: Int = 56, + eee: Int = 57, + fff: Int = 58, + ggg: Int = 59, + hhh: Int = 60, + iii: Int = 61, + jjj: Int = 62, + kkk: Int = 63, + lll: Int = 64, + mmm: Int = 65, + nnn: Int = 66, + ooo: Int = 67, + ppp: Int = 68, + qqq: Int = 69, + rrr: Int = 70): String { + return "$a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z $aa $bb $cc $dd $ee $ff $gg $hh $ii $jj $kk " + + "$ll $mm $nn $oo $pp $qq $rr $ss $tt $uu $vv $ww $xx $yy $zz $aaa $bbb $ccc $ddd $eee $fff $ggg $hhh $iii $jjj $kkk $lll " + + "$mmm $nnn $ooo $ppp $qqq $rrr" +} + +fun box(): String { + val test1 = 1.foo(4, e = 8, f = 15, w = 16, aa = 23, ff = 42) + val test2 = 1.foo() + val test3 = 1.foo(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, q = 16, r = 15, s = 14, t = 13, + u = 12, v = 11, w = 10, x = 9, y = 8, z = 7, aa = 6, bb = 5, cc = 4, dd = 3, ee = 2, ff = 1) + if (test1 != "4 2 3 4 8 15 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 16 24 25 26 23 28 29 30 31 42") { + return "test1 = $test1" + } + if (test2 != "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32") { + return "test2 = $test2" + } + if (test3 != "32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1") { + return "test3 = $test3" + } + + val test4 = "".bar(54, 217, h = 236, l = 18, q = 3216, u = 8, aa = 22, ff = 33, jj = 44, mm = 55) + val test5 = "".bar() + val test6 = "".bar(40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, u = 20, v = 19, + w = 18, x = 17, y = 16, z = 15, aa = 14, bb = 13, cc = 12, dd = 11, ee = 10, ff = 9, gg = 8, hh = 7, ii = 6, + jj = 5, kk = 4, ll = 3, mm = 2, nn = 1) + if (test4 != "54 217 3 4 5 6 7 236 9 10 11 18 13 14 15 16 3216 18 19 20 8 22 23 24 25 26 22 28 29 30 31 33 33 34 35 44 37 38 55 40") { + return "test4 = $test4" + } + if (test5 != "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40") { + return "test5 = $test5" + } + if (test6 != "40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1") { + return "test6 = $test6" + } + + val test7 = 'a'.baz(5, f = 3, w = 1, aa = 71, nn = 2, qq = 15, ww = 97, aaa = 261258, iii = 3, nnn = 8, rrr = 7) + val test8 = 'a'.baz() + val test9 = 'a'.baz(70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, + 40, 39, 38, 37, 36, jj = 35, kk = 34, ll = 33, mm = 32, nn = 31, oo = 30, pp = 29, qq = 28, rr = 27, ss = 26, tt = 25, + uu = 24, vv = 23, ww = 22, xx = 21, yy = 20, zz = 19, aaa = 18, bbb = 17, ccc = 16, ddd = 15, eee = 14, fff = 13, + ggg = 12, hhh = 11, iii = 10, jjj = 9, kkk = 8, lll = 7, mmm = 6, nnn = 5, ooo = 4, ppp = 3, qqq = 2, rrr = 1) + if (test7 != "5 2 3 4 5 3 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 24 25 26 71 28 29 30 31 32 33 34 35 36 37 38 39 2 41 42 15 " + + "44 45 46 47 48 97 50 51 52 261258 54 55 56 57 58 59 60 3 62 63 64 65 8 67 68 69 7") { + return "test7 = $test7" + } + if (test8 != "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 " + + "43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70") { + return "test8 = $test8" + } + if (test9 != "70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 " + + "31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1") { + return "test9 = $test9" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunction.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunction.kt new file mode 100644 index 00000000000..b985d4b6467 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunction.kt @@ -0,0 +1,9 @@ +fun Int.foo(a: Int = 1): Int { + return a +} + +fun box(): String { + if (1.foo() != 1) return "fail" + if (1.foo(2) != 2) return "fail" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunctionDouble.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunctionDouble.kt new file mode 100644 index 00000000000..8b4b1fbd712 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunctionDouble.kt @@ -0,0 +1,9 @@ +fun Double.foo(a: Double = 1.0): Double { + return a +} + +fun box(): String { + if (1.0.foo() != 1.0) return "fail" + if (1.0.foo(2.0) != 2.0) return "fail" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunctionDoubleTwoArgs.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunctionDoubleTwoArgs.kt new file mode 100644 index 00000000000..9c36a1335a3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunctionDoubleTwoArgs.kt @@ -0,0 +1,11 @@ +fun Double.foo(a: Double = 1.0, b: Double = 1.0): Double { + return a + b +} + +fun box(): String { + if (1.0.foo() != 2.0) return "fail" + if (1.0.foo(2.0, 2.0) != 4.0) return "fail" + if (1.0.foo(a = 2.0) != 3.0) return "fail" + if (1.0.foo(b = 2.0) != 3.0) return "fail" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunctionInClassObject.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunctionInClassObject.kt new file mode 100644 index 00000000000..876be1766c2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunctionInClassObject.kt @@ -0,0 +1,17 @@ +class A { + companion object { + fun Int.foo(a: Int = 1): Int { + return a + } + + fun test(): String { + if (1.foo() != 1) return "fail" + if (1.foo(2) != 2) return "fail" + return "OK" + } + } +} + +fun box(): String { + return A.test() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunctionInObject.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunctionInObject.kt new file mode 100644 index 00000000000..d16105ac6b3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunctionInObject.kt @@ -0,0 +1,15 @@ +object A { + fun Int.foo(a: Int = 1): Int { + return a + } + + fun test(): String { + if (1.foo() != 1) return "fail" + if (1.foo(2) != 2) return "fail" + return "OK" + } +} + +fun box(): String { + return A.test() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunctionWithOneDefArg.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunctionWithOneDefArg.kt new file mode 100644 index 00000000000..c905daed1b2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/extentionFunctionWithOneDefArg.kt @@ -0,0 +1,9 @@ +fun Int.foo(a: Int = 1, b: String): Int { + return a +} + +fun box(): String { + if (1.foo(b = "b") != 1) return "fail" + if (1.foo(2, "b") != 2) return "fail" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/funInTrait.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/funInTrait.kt new file mode 100644 index 00000000000..06b181e10b6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/funInTrait.kt @@ -0,0 +1,14 @@ +interface Foo { + fun foo(a: Double = 1.0): Double +} + +class FooImpl : Foo { + override fun foo(a: Double): Double { + return a + } +} +fun box(): String { + if (FooImpl().foo() != 1.0) return "fail" + if (FooImpl().foo(2.0) != 2.0) return "fail" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/innerExtentionFunction.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/innerExtentionFunction.kt new file mode 100644 index 00000000000..35a3e575fe4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/innerExtentionFunction.kt @@ -0,0 +1,15 @@ +class A { + fun Int.foo(a: Int = 1): Int { + return a + } + + fun test(): String { + if (1.foo() != 1) return "fail" + if (1.foo(2) != 2) return "fail" + return "OK" + } +} + +fun box(): String { + return A().test() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/innerExtentionFunctionDouble.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/innerExtentionFunctionDouble.kt new file mode 100644 index 00000000000..a18b571e32b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/innerExtentionFunctionDouble.kt @@ -0,0 +1,15 @@ +class A { + fun Double.foo(a: Double = 1.0): Double { + return a + } + + fun test(): String { + if (1.0.foo() != 1.0) return "fail" + if (1.0.foo(2.0) != 2.0) return "fail" + return "OK" + } +} + +fun box(): String { + return A().test() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/innerExtentionFunctionDoubleTwoArgs.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/innerExtentionFunctionDoubleTwoArgs.kt new file mode 100644 index 00000000000..844f5e88ef4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/innerExtentionFunctionDoubleTwoArgs.kt @@ -0,0 +1,17 @@ +class A { + fun Double.foo(a: Double = 1.0, b: Double = 1.0): Double { + return a + b + } + + fun test(): String { + if (1.0.foo() != 2.0) return "fail" + if (1.0.foo(2.0, 2.0) != 4.0) return "fail" + if (1.0.foo(a = 2.0) != 3.0) return "fail" + if (1.0.foo(b = 2.0) != 3.0) return "fail" + return "OK" + } +} + +fun box(): String { + return A().test() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/innerExtentionFunctionManyArgs.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/innerExtentionFunctionManyArgs.kt new file mode 100644 index 00000000000..3ed1be3d6c4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/innerExtentionFunctionManyArgs.kt @@ -0,0 +1,211 @@ +class A { + fun Int.foo(a: Int = 1, + b: Int = 2, + c: Int = 3, + d: Int = 4, + e: Int = 5, + f: Int = 6, + g: Int = 7, + h: Int = 8, + i: Int = 9, + j: Int = 10, + k: Int = 11, + l: Int = 12, + m: Int = 13, + n: Int = 14, + o: Int = 15, + p: Int = 16, + q: Int = 17, + r: Int = 18, + s: Int = 19, + t: Int = 20, + u: Int = 21, + v: Int = 22, + w: Int = 23, + x: Int = 24, + y: Int = 25, + z: Int = 26, + aa: Int = 27, + bb: Int = 28, + cc: Int = 29, + dd: Int = 30, + ee: Int = 31, + ff: Int = 32): String { + return "$a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z $aa $bb $cc $dd $ee $ff" + } + + fun String.bar(a: Int = 1, + b: Int = 2, + c: Int = 3, + d: Int = 4, + e: Int = 5, + f: Int = 6, + g: Int = 7, + h: Int = 8, + i: Int = 9, + j: Int = 10, + k: Int = 11, + l: Int = 12, + m: Int = 13, + n: Int = 14, + o: Int = 15, + p: Int = 16, + q: Int = 17, + r: Int = 18, + s: Int = 19, + t: Int = 20, + u: Int = 21, + v: Int = 22, + w: Int = 23, + x: Int = 24, + y: Int = 25, + z: Int = 26, + aa: Int = 27, + bb: Int = 28, + cc: Int = 29, + dd: Int = 30, + ee: Int = 31, + ff: Int = 32, + gg: Int = 33, + hh: Int = 34, + ii: Int = 35, + jj: Int = 36, + kk: Int = 37, + ll: Int = 38, + mm: Int = 39, + nn: Int = 40): String { + return "$a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z $aa $bb $cc $dd $ee $ff " + + "$gg $hh $ii $jj $kk $ll $mm $nn" + } + + fun Char.baz(a: Int = 1, + b: Int = 2, + c: Int = 3, + d: Int = 4, + e: Int = 5, + f: Int = 6, + g: Int = 7, + h: Int = 8, + i: Int = 9, + j: Int = 10, + k: Int = 11, + l: Int = 12, + m: Int = 13, + n: Int = 14, + o: Int = 15, + p: Int = 16, + q: Int = 17, + r: Int = 18, + s: Int = 19, + t: Int = 20, + u: Int = 21, + v: Int = 22, + w: Int = 23, + x: Int = 24, + y: Int = 25, + z: Int = 26, + aa: Int = 27, + bb: Int = 28, + cc: Int = 29, + dd: Int = 30, + ee: Int = 31, + ff: Int = 32, + gg: Int = 33, + hh: Int = 34, + ii: Int = 35, + jj: Int = 36, + kk: Int = 37, + ll: Int = 38, + mm: Int = 39, + nn: Int = 40, + oo: Int = 41, + pp: Int = 42, + qq: Int = 43, + rr: Int = 44, + ss: Int = 45, + tt: Int = 46, + uu: Int = 47, + vv: Int = 48, + ww: Int = 49, + xx: Int = 50, + yy: Int = 51, + zz: Int = 52, + aaa: Int = 53, + bbb: Int = 54, + ccc: Int = 55, + ddd: Int = 56, + eee: Int = 57, + fff: Int = 58, + ggg: Int = 59, + hhh: Int = 60, + iii: Int = 61, + jjj: Int = 62, + kkk: Int = 63, + lll: Int = 64, + mmm: Int = 65, + nnn: Int = 66, + ooo: Int = 67, + ppp: Int = 68, + qqq: Int = 69, + rrr: Int = 70): String { + return "$a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z $aa $bb $cc $dd $ee $ff $gg $hh $ii $jj $kk " + + "$ll $mm $nn $oo $pp $qq $rr $ss $tt $uu $vv $ww $xx $yy $zz $aaa $bbb $ccc $ddd $eee $fff $ggg $hhh $iii $jjj $kkk $lll " + + "$mmm $nnn $ooo $ppp $qqq $rrr" + } + + fun test(): String { + val test1 = 1.foo(4, e = 8, f = 15, w = 16, aa = 23, ff = 42) + val test2 = 1.foo() + val test3 = 1.foo(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, q = 16, r = 15, s = 14, t = 13, + u = 12, v = 11, w = 10, x = 9, y = 8, z = 7, aa = 6, bb = 5, cc = 4, dd = 3, ee = 2, ff = 1) + if (test1 != "4 2 3 4 8 15 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 16 24 25 26 23 28 29 30 31 42") { + return "test1 = $test1" + } + if (test2 != "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32") { + return "test2 = $test2" + } + if (test3 != "32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1") { + return "test3 = $test3" + } + + val test4 = "".bar(54, 217, h = 236, l = 18, q = 3216, u = 8, aa = 22, ff = 33, jj = 44, mm = 55) + val test5 = "".bar() + val test6 = "".bar(40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, u = 20, v = 19, + w = 18, x = 17, y = 16, z = 15, aa = 14, bb = 13, cc = 12, dd = 11, ee = 10, ff = 9, gg = 8, hh = 7, ii = 6, + jj = 5, kk = 4, ll = 3, mm = 2, nn = 1) + if (test4 != "54 217 3 4 5 6 7 236 9 10 11 18 13 14 15 16 3216 18 19 20 8 22 23 24 25 26 22 28 29 30 31 33 33 34 35 44 37 38 55 40") { + return "test4 = $test4" + } + if (test5 != "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40") { + return "test5 = $test5" + } + if (test6 != "40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1") { + return "test6 = $test6" + } + + val test7 = 'a'.baz(5, f = 3, w = 1, aa = 71, nn = 2, qq = 15, ww = 97, aaa = 261258, iii = 3, nnn = 8, rrr = 7) + val test8 = 'a'.baz() + val test9 = 'a'.baz(70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, + 40, 39, 38, 37, 36, jj = 35, kk = 34, ll = 33, mm = 32, nn = 31, oo = 30, pp = 29, qq = 28, rr = 27, ss = 26, tt = 25, + uu = 24, vv = 23, ww = 22, xx = 21, yy = 20, zz = 19, aaa = 18, bbb = 17, ccc = 16, ddd = 15, eee = 14, fff = 13, + ggg = 12, hhh = 11, iii = 10, jjj = 9, kkk = 8, lll = 7, mmm = 6, nnn = 5, ooo = 4, ppp = 3, qqq = 2, rrr = 1) + if (test7 != "5 2 3 4 5 3 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 24 25 26 71 28 29 30 31 32 33 34 35 36 37 38 39 2 41 42 15 " + + "44 45 46 47 48 97 50 51 52 261258 54 55 56 57 58 59 60 3 62 63 64 65 8 67 68 69 7") { + return "test7 = $test7" + } + if (test8 != "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 " + + "43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70") { + return "test8 = $test8" + } + if (test9 != "70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 " + + "31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1") { + return "test9 = $test9" + } + + return "OK" + } +} + +fun box(): String { + return A().test() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/kt5232.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/kt5232.kt new file mode 100644 index 00000000000..8b91d2bd2d5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/kt5232.kt @@ -0,0 +1,14 @@ +interface A { + fun visit(a:String, b:String="") : String = b + a +} + +class B : A { + override fun visit(a:String, b:String) : String = b + a +} + +fun box(): String { + val result = B().visit("K", "O") + if (result != "OK") return "fail $result" + + return B().visit("OK") +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/memberFunctionManyArgs.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/memberFunctionManyArgs.kt new file mode 100644 index 00000000000..def2549e106 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/memberFunctionManyArgs.kt @@ -0,0 +1,208 @@ +class A() { + fun foo(a: Int = 1, + b: Int = 2, + c: Int = 3, + d: Int = 4, + e: Int = 5, + f: Int = 6, + g: Int = 7, + h: Int = 8, + i: Int = 9, + j: Int = 10, + k: Int = 11, + l: Int = 12, + m: Int = 13, + n: Int = 14, + o: Int = 15, + p: Int = 16, + q: Int = 17, + r: Int = 18, + s: Int = 19, + t: Int = 20, + u: Int = 21, + v: Int = 22, + w: Int = 23, + x: Int = 24, + y: Int = 25, + z: Int = 26, + aa: Int = 27, + bb: Int = 28, + cc: Int = 29, + dd: Int = 30, + ee: Int = 31, + ff: Int = 32): String { + return "$a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z $aa $bb $cc $dd $ee $ff" + } + + fun bar(a: Int = 1, + b: Int = 2, + c: Int = 3, + d: Int = 4, + e: Int = 5, + f: Int = 6, + g: Int = 7, + h: Int = 8, + i: Int = 9, + j: Int = 10, + k: Int = 11, + l: Int = 12, + m: Int = 13, + n: Int = 14, + o: Int = 15, + p: Int = 16, + q: Int = 17, + r: Int = 18, + s: Int = 19, + t: Int = 20, + u: Int = 21, + v: Int = 22, + w: Int = 23, + x: Int = 24, + y: Int = 25, + z: Int = 26, + aa: Int = 27, + bb: Int = 28, + cc: Int = 29, + dd: Int = 30, + ee: Int = 31, + ff: Int = 32, + gg: Int = 33, + hh: Int = 34, + ii: Int = 35, + jj: Int = 36, + kk: Int = 37, + ll: Int = 38, + mm: Int = 39, + nn: Int = 40): String { + return "$a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z $aa $bb $cc $dd $ee $ff " + + "$gg $hh $ii $jj $kk $ll $mm $nn" + } + + fun baz(a: Int = 1, + b: Int = 2, + c: Int = 3, + d: Int = 4, + e: Int = 5, + f: Int = 6, + g: Int = 7, + h: Int = 8, + i: Int = 9, + j: Int = 10, + k: Int = 11, + l: Int = 12, + m: Int = 13, + n: Int = 14, + o: Int = 15, + p: Int = 16, + q: Int = 17, + r: Int = 18, + s: Int = 19, + t: Int = 20, + u: Int = 21, + v: Int = 22, + w: Int = 23, + x: Int = 24, + y: Int = 25, + z: Int = 26, + aa: Int = 27, + bb: Int = 28, + cc: Int = 29, + dd: Int = 30, + ee: Int = 31, + ff: Int = 32, + gg: Int = 33, + hh: Int = 34, + ii: Int = 35, + jj: Int = 36, + kk: Int = 37, + ll: Int = 38, + mm: Int = 39, + nn: Int = 40, + oo: Int = 41, + pp: Int = 42, + qq: Int = 43, + rr: Int = 44, + ss: Int = 45, + tt: Int = 46, + uu: Int = 47, + vv: Int = 48, + ww: Int = 49, + xx: Int = 50, + yy: Int = 51, + zz: Int = 52, + aaa: Int = 53, + bbb: Int = 54, + ccc: Int = 55, + ddd: Int = 56, + eee: Int = 57, + fff: Int = 58, + ggg: Int = 59, + hhh: Int = 60, + iii: Int = 61, + jjj: Int = 62, + kkk: Int = 63, + lll: Int = 64, + mmm: Int = 65, + nnn: Int = 66, + ooo: Int = 67, + ppp: Int = 68, + qqq: Int = 69, + rrr: Int = 70): String { + return "$a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z $aa $bb $cc $dd $ee $ff $gg $hh $ii $jj $kk " + + "$ll $mm $nn $oo $pp $qq $rr $ss $tt $uu $vv $ww $xx $yy $zz $aaa $bbb $ccc $ddd $eee $fff $ggg $hhh $iii $jjj $kkk $lll " + + "$mmm $nnn $ooo $ppp $qqq $rrr" + } +} + +fun box(): String { + val a = A() + val test1 = a.foo(4, e = 8, f = 15, w = 16, aa = 23, ff = 42) + val test2 = a.foo() + val test3 = a.foo(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, q = 16, r = 15, s = 14, t = 13, + u = 12, v = 11, w = 10, x = 9, y = 8, z = 7, aa = 6, bb = 5, cc = 4, dd = 3, ee = 2, ff = 1) + if (test1 != "4 2 3 4 8 15 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 16 24 25 26 23 28 29 30 31 42") { + return "test1 = $test1" + } + if (test2 != "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32") { + return "test2 = $test2" + } + if (test3 != "32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1") { + return "test3 = $test3" + } + + val test4 = a.bar(54, 217, h = 236, l = 18, q = 3216, u = 8, aa = 22, ff = 33, jj = 44, mm = 55) + val test5 = a.bar() + val test6 = a.bar(40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, u = 20, v = 19, + w = 18, x = 17, y = 16, z = 15, aa = 14, bb = 13, cc = 12, dd = 11, ee = 10, ff = 9, gg = 8, hh = 7, ii = 6, + jj = 5, kk = 4, ll = 3, mm = 2, nn = 1) + if (test4 != "54 217 3 4 5 6 7 236 9 10 11 18 13 14 15 16 3216 18 19 20 8 22 23 24 25 26 22 28 29 30 31 33 33 34 35 44 37 38 55 40") { + return "test4 = $test4" + } + if (test5 != "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40") { + return "test5 = $test5" + } + if (test6 != "40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1") { + return "test6 = $test6" + } + + val test7 = a.baz(5, f = 3, w = 1, aa = 71, nn = 2, qq = 15, ww = 97, aaa = 261258, iii = 3, nnn = 8, rrr = 7) + val test8 = a.baz() + val test9 = a.baz(70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, + 40, 39, 38, 37, 36, jj = 35, kk = 34, ll = 33, mm = 32, nn = 31, oo = 30, pp = 29, qq = 28, rr = 27, ss = 26, tt = 25, + uu = 24, vv = 23, ww = 22, xx = 21, yy = 20, zz = 19, aaa = 18, bbb = 17, ccc = 16, ddd = 15, eee = 14, fff = 13, + ggg = 12, hhh = 11, iii = 10, jjj = 9, kkk = 8, lll = 7, mmm = 6, nnn = 5, ooo = 4, ppp = 3, qqq = 2, rrr = 1) + if (test7 != "5 2 3 4 5 3 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 24 25 26 71 28 29 30 31 32 33 34 35 36 37 38 39 2 41 42 15 " + + "44 45 46 47 48 97 50 51 52 261258 54 55 56 57 58 59 60 3 62 63 64 65 8 67 68 69 7") { + return "test7 = $test7" + } + if (test8 != "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 " + + "43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70") { + return "test8 = $test8" + } + if (test9 != "70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 " + + "31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1") { + return "test9 = $test9" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/mixingNamedAndPositioned.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/mixingNamedAndPositioned.kt new file mode 100644 index 00000000000..7b3aebeec18 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/mixingNamedAndPositioned.kt @@ -0,0 +1,16 @@ +fun foo(a: String = "Companion", b: Int = 1, c: Long = 2): String { + return "$a $b $c" +} + +fun box(): String { + val test1 = foo("test1", 2, c = 3) + if (test1 != "test1 2 3") return test1 + + val test2 = foo("test2", c = 3) + if (test2 != "test2 1 3") return test2 + + val test3 = foo("test3", b = 3) + if (test3 != "test3 3 2") return test3 + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/topLevelManyArgs.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/topLevelManyArgs.kt new file mode 100644 index 00000000000..1086f23b45f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/topLevelManyArgs.kt @@ -0,0 +1,205 @@ +fun foo(a: Int = 1, + b: Int = 2, + c: Int = 3, + d: Int = 4, + e: Int = 5, + f: Int = 6, + g: Int = 7, + h: Int = 8, + i: Int = 9, + j: Int = 10, + k: Int = 11, + l: Int = 12, + m: Int = 13, + n: Int = 14, + o: Int = 15, + p: Int = 16, + q: Int = 17, + r: Int = 18, + s: Int = 19, + t: Int = 20, + u: Int = 21, + v: Int = 22, + w: Int = 23, + x: Int = 24, + y: Int = 25, + z: Int = 26, + aa: Int = 27, + bb: Int = 28, + cc: Int = 29, + dd: Int = 30, + ee: Int = 31, + ff: Int = 32): String { + return "$a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z $aa $bb $cc $dd $ee $ff" +} + +fun bar(a: Int = 1, + b: Int = 2, + c: Int = 3, + d: Int = 4, + e: Int = 5, + f: Int = 6, + g: Int = 7, + h: Int = 8, + i: Int = 9, + j: Int = 10, + k: Int = 11, + l: Int = 12, + m: Int = 13, + n: Int = 14, + o: Int = 15, + p: Int = 16, + q: Int = 17, + r: Int = 18, + s: Int = 19, + t: Int = 20, + u: Int = 21, + v: Int = 22, + w: Int = 23, + x: Int = 24, + y: Int = 25, + z: Int = 26, + aa: Int = 27, + bb: Int = 28, + cc: Int = 29, + dd: Int = 30, + ee: Int = 31, + ff: Int = 32, + gg: Int = 33, + hh: Int = 34, + ii: Int = 35, + jj: Int = 36, + kk: Int = 37, + ll: Int = 38, + mm: Int = 39, + nn: Int = 40): String { + return "$a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z $aa $bb $cc $dd $ee $ff " + + "$gg $hh $ii $jj $kk $ll $mm $nn" +} + +fun baz(a: Int = 1, + b: Int = 2, + c: Int = 3, + d: Int = 4, + e: Int = 5, + f: Int = 6, + g: Int = 7, + h: Int = 8, + i: Int = 9, + j: Int = 10, + k: Int = 11, + l: Int = 12, + m: Int = 13, + n: Int = 14, + o: Int = 15, + p: Int = 16, + q: Int = 17, + r: Int = 18, + s: Int = 19, + t: Int = 20, + u: Int = 21, + v: Int = 22, + w: Int = 23, + x: Int = 24, + y: Int = 25, + z: Int = 26, + aa: Int = 27, + bb: Int = 28, + cc: Int = 29, + dd: Int = 30, + ee: Int = 31, + ff: Int = 32, + gg: Int = 33, + hh: Int = 34, + ii: Int = 35, + jj: Int = 36, + kk: Int = 37, + ll: Int = 38, + mm: Int = 39, + nn: Int = 40, + oo: Int = 41, + pp: Int = 42, + qq: Int = 43, + rr: Int = 44, + ss: Int = 45, + tt: Int = 46, + uu: Int = 47, + vv: Int = 48, + ww: Int = 49, + xx: Int = 50, + yy: Int = 51, + zz: Int = 52, + aaa: Int = 53, + bbb: Int = 54, + ccc: Int = 55, + ddd: Int = 56, + eee: Int = 57, + fff: Int = 58, + ggg: Int = 59, + hhh: Int = 60, + iii: Int = 61, + jjj: Int = 62, + kkk: Int = 63, + lll: Int = 64, + mmm: Int = 65, + nnn: Int = 66, + ooo: Int = 67, + ppp: Int = 68, + qqq: Int = 69, + rrr: Int = 70): String { + return "$a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z $aa $bb $cc $dd $ee $ff $gg $hh $ii $jj $kk " + + "$ll $mm $nn $oo $pp $qq $rr $ss $tt $uu $vv $ww $xx $yy $zz $aaa $bbb $ccc $ddd $eee $fff $ggg $hhh $iii $jjj $kkk $lll " + + "$mmm $nnn $ooo $ppp $qqq $rrr" +} + +fun box(): String { + val test1 = foo(4, e = 8, f = 15, w = 16, aa = 23, ff = 42) + val test2 = foo() + val test3 = foo(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, q = 16, r = 15, s = 14, t = 13, + u = 12, v = 11, w = 10, x = 9, y = 8, z = 7, aa = 6, bb = 5, cc = 4, dd = 3, ee = 2, ff = 1) + if (test1 != "4 2 3 4 8 15 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 16 24 25 26 23 28 29 30 31 42") { + return "test1 = $test1" + } + if (test2 != "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32") { + return "test2 = $test2" + } + if (test3 != "32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1") { + return "test3 = $test3" + } + + val test4 = bar(54, 217, h = 236, l = 18, q = 3216, u = 8, aa = 22, ff = 33, jj = 44, mm = 55) + val test5 = bar() + val test6 = bar(40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, u = 20, v = 19, + w = 18, x = 17, y = 16, z = 15, aa = 14, bb = 13, cc = 12, dd = 11, ee = 10, ff = 9, gg = 8, hh = 7, ii = 6, + jj = 5, kk = 4, ll = 3, mm = 2, nn = 1) + if (test4 != "54 217 3 4 5 6 7 236 9 10 11 18 13 14 15 16 3216 18 19 20 8 22 23 24 25 26 22 28 29 30 31 33 33 34 35 44 37 38 55 40") { + return "test4 = $test4" + } + if (test5 != "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40") { + return "test5 = $test5" + } + if (test6 != "40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1") { + return "test6 = $test6" + } + + val test7 = baz(5, f = 3, w = 1, aa = 71, nn = 2, qq = 15, ww = 97, aaa = 261258, iii = 3, nnn = 8, rrr = 7) + val test8 = baz() + val test9 = baz(70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, + 40, 39, 38, 37, 36, jj = 35, kk = 34, ll = 33, mm = 32, nn = 31, oo = 30, pp = 29, qq = 28, rr = 27, ss = 26, tt = 25, + uu = 24, vv = 23, ww = 22, xx = 21, yy = 20, zz = 19, aaa = 18, bbb = 17, ccc = 16, ddd = 15, eee = 14, fff = 13, + ggg = 12, hhh = 11, iii = 10, jjj = 9, kkk = 8, lll = 7, mmm = 6, nnn = 5, ooo = 4, ppp = 3, qqq = 2, rrr = 1) + if (test7 != "5 2 3 4 5 3 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1 24 25 26 71 28 29 30 31 32 33 34 35 36 37 38 39 2 41 42 15 " + + "44 45 46 47 48 97 50 51 52 261258 54 55 56 57 58 59 60 3 62 63 64 65 8 67 68 69 7") { + return "test7 = $test7" + } + if (test8 != "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 " + + "43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70") { + return "test8 = $test8" + } + if (test9 != "70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 " + + "31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1") { + return "test9 = $test9" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/function/trait.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/trait.kt new file mode 100644 index 00000000000..91bafe072f3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/function/trait.kt @@ -0,0 +1,14 @@ +interface Base { + fun bar(a: String = "abc"): String = a + " from interface" +} + +class Derived: Base { + override fun bar(a: String): String = a + " from class" +} + +fun box(): String { + val result = Derived().bar() + if (result != "abc from class") return "Fail: $result" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/kt6382.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/kt6382.kt new file mode 100644 index 00000000000..07910e2cf12 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/kt6382.kt @@ -0,0 +1,16 @@ +// WITH_RUNTIME + +fun box(): String { + return if (A().run() == "Aabc") "OK" else "fail" +} + +public class A { + fun run() = + with ("abc") { + show() + } + + private fun String.show(p: Boolean = false): String = getName() + this + + private fun getName() = "A" +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/private/memberExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/private/memberExtensionFunction.kt new file mode 100644 index 00000000000..01167805ef4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/private/memberExtensionFunction.kt @@ -0,0 +1,9 @@ +class A { + private fun Int.foo(other: Int = 5): Int = this + other + + inner class B { + fun bar() = 37.foo() + } +} + +fun box() = if (A().B().bar() == 42) "OK" else "Fail" diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/private/memberFunction.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/private/memberFunction.kt new file mode 100644 index 00000000000..64fe7c2de65 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/private/memberFunction.kt @@ -0,0 +1,11 @@ +// KT-5786 NoSuchMethodError: no accessor for private fun with default arguments + +class A { + private fun foo(result: String = "OK"): String = result + + companion object { + fun bar() = A().foo() + } +} + +fun box() = A.bar() diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/private/primaryConstructor.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/private/primaryConstructor.kt new file mode 100644 index 00000000000..7b4ba263678 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/private/primaryConstructor.kt @@ -0,0 +1,16 @@ +var state: String = "Fail" + +class A private constructor(x: String = "OK") { + init { + state = x + } + + companion object { + fun foo() = A() + } +} + +fun box(): String { + A.foo() + return state +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/private/secondaryConstructor.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/private/secondaryConstructor.kt new file mode 100644 index 00000000000..ea7569669e5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/private/secondaryConstructor.kt @@ -0,0 +1,16 @@ +var state: String = "Fail" + +class A { + private constructor(x: String = "OK") { + state = x + } + + companion object { + fun foo() = A() + } +} + +fun box(): String { + A.foo() + return state +} diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/protected.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/protected.kt new file mode 100644 index 00000000000..be1243f96c6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/protected.kt @@ -0,0 +1,23 @@ +// FILE: Foo.kt + +package foo + +open class Foo() { + protected fun foo(value: Boolean = false) = if (!value) "OK" else "fail5" +} + +// FILE: Bar.kt + +package bar + +import foo.Foo + +class Bar() : Foo() { + fun execute(): String { + return { foo() } () + } +} + +fun box(): String { + return Bar().execute() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/signature/kt2789.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/signature/kt2789.kt new file mode 100644 index 00000000000..043b0d071a3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/signature/kt2789.kt @@ -0,0 +1,23 @@ +interface FooTrait { + fun make(size: Int = 16) : T + + fun makeFromTraitImpl() : T = make() +} + +class FooClass : FooTrait { + override fun make(size: Int): String { + return "$size" + } +} + +fun box(): String { + val explicitParam = FooClass().make(16) + val defaultRes = FooClass().make() + val defaultTraitRes = FooClass().makeFromTraitImpl() + if (explicitParam != defaultRes) return "fail 1: ${explicitParam} != ${defaultRes}" + if (explicitParam != "16") return "fail 2: ${explicitParam}" + + if (explicitParam != defaultTraitRes) return "fail 3: ${explicitParam} != ${defaultTraitRes}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/signature/kt9428.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/signature/kt9428.kt new file mode 100644 index 00000000000..b9d89105d37 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/signature/kt9428.kt @@ -0,0 +1,23 @@ +open class Player(val name: String) +open class SlashPlayer(name: String) : Player(name) + +public abstract class Game { + abstract fun getPlayer(name: String, create: Boolean = true): T? +} + +class SimpleGame : Game() { + override fun getPlayer(name: String, create: Boolean): SlashPlayer? { + return if (create) { + SlashPlayer(name) + } + else null + } +} + +fun box(): String { + val player1 = SimpleGame().getPlayer("fail", false) + if (player1 != null) return "fail 1" + + val player2 = SimpleGame().getPlayer("OK") + return player2!!.name +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/signature/kt9924.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/signature/kt9924.kt new file mode 100644 index 00000000000..8366f26008e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/signature/kt9924.kt @@ -0,0 +1,13 @@ +abstract class A { + abstract fun test(a: T, b:Boolean = false) : String +} + +class B : A() { + override fun test(a: String, b: Boolean): String { + return a + } +} + +fun box(): String { + return B().test("OK") +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/simpleFromOtherFile.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/simpleFromOtherFile.kt new file mode 100644 index 00000000000..e039250e9ef --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/simpleFromOtherFile.kt @@ -0,0 +1,7 @@ +// FILE: 1.kt + +fun box() = ok() + +// FILE: 2.kt + +fun ok(res: String = "OK") = res diff --git a/backend.native/tests/external/codegen/blackbox/defaultArguments/superCallCheck.kt b/backend.native/tests/external/codegen/blackbox/defaultArguments/superCallCheck.kt new file mode 100644 index 00000000000..918a68ed0d8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/defaultArguments/superCallCheck.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +open class MyClass { + fun def(i: Int = 0): Int { + return i + } +} + +fun box():String { + val method = MyClass::class.java.getMethod("def\$default", MyClass::class.java, Int::class.java, Int::class.java, Any::class.java) + val result = method.invoke(null, MyClass(), -1, 1, null) + + if (result != 0) return "fail 1: $result" + + var failed = false + try { + method.invoke(null, MyClass(), -1, 1, "fail") + } + catch(e: Exception) { + val cause = e.cause + if (cause is UnsupportedOperationException && cause.message!!.startsWith("Super calls")) { + failed = true + } + } + + return if (!failed) "fail" else "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/accessTopLevelDelegatedPropertyInClinit.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/accessTopLevelDelegatedPropertyInClinit.kt new file mode 100644 index 00000000000..b409bd753ab --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/accessTopLevelDelegatedPropertyInClinit.kt @@ -0,0 +1,15 @@ +import kotlin.reflect.KProperty + +// KT-5612 + +class Delegate { + operator fun getValue(thisRef: Any?, prop: KProperty<*>): String { + return "OK" + } +} + +val prop by Delegate() + +val a = prop + +fun box() = a diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/capturePropertyInClosure.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/capturePropertyInClosure.kt new file mode 100644 index 00000000000..3c03bc94ca8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/capturePropertyInClosure.kt @@ -0,0 +1,23 @@ +import kotlin.reflect.KProperty + +class Delegate { + var inner = 1 + operator fun getValue(t: Any?, p: KProperty<*>): Int = inner + operator fun setValue(t: Any?, p: KProperty<*>, i: Int) { inner = i } +} + +class B { + private var value: Int by Delegate() + + public fun test() { + fun foo() { + value = 1 + } + foo() + } +} + +fun box(): String { + B().test() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/castGetReturnType.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/castGetReturnType.kt new file mode 100644 index 00000000000..cc106890792 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/castGetReturnType.kt @@ -0,0 +1,13 @@ +import kotlin.reflect.KProperty + +class Delegate { + operator fun getValue(t: Any?, p: KProperty<*>): Int = 1 +} + +class AImpl { + val prop: Number by Delegate() +} + +fun box(): String { + return if(AImpl().prop == 1) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/castSetParameter.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/castSetParameter.kt new file mode 100644 index 00000000000..3d3e7a7806a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/castSetParameter.kt @@ -0,0 +1,26 @@ +import kotlin.reflect.KProperty + +class Delegate { + var inner = Derived() + operator fun getValue(t: Any?, p: KProperty<*>): Derived { + inner = Derived(inner.a + "-get") + return inner + } + operator fun setValue(t: Any?, p: KProperty<*>, i: Base) { inner = Derived(inner.a + "-" + i.a + "-set") } +} + +class A { + var prop: Derived by Delegate() +} + +fun box(): String { + val c = A() + if(c.prop.a != "derived-get") return "fail get ${c.prop.a}" + c.prop = Derived() + if (c.prop.a != "derived-get-derived-set-get") return "fail set ${c.prop.a}" + return "OK" +} + +open class Base(open val a: String = "base") + +class Derived(override val a: String = "derived"): Base() diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateAsInnerClass.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateAsInnerClass.kt new file mode 100644 index 00000000000..9b503ccce83 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateAsInnerClass.kt @@ -0,0 +1,19 @@ +import kotlin.reflect.KProperty + +class A { + var prop: Int by Delegate() + + class Delegate { + var inner = 1 + operator fun getValue(t: Any?, p: KProperty<*>): Int = inner + operator fun setValue(t: Any?, p: KProperty<*>, i: Int) { inner = i } + } +} + +fun box(): String { + val c = A() + if(c.prop != 1) return "fail get" + c.prop = 2 + if (c.prop != 2) return "fail set" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateByOtherProperty.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateByOtherProperty.kt new file mode 100644 index 00000000000..7ec7f0c9151 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateByOtherProperty.kt @@ -0,0 +1,20 @@ +import kotlin.reflect.KProperty + +class Delegate { + var inner = 1 + operator fun getValue(t: Any?, p: KProperty<*>): Int = inner + operator fun setValue(t: Any?, p: KProperty<*>, i: Int) { inner = i } +} + +class A { + val p = Delegate() + var prop: Int by p +} + +fun box(): String { + val c = A() + if(c.prop != 1) return "fail get" + c.prop = 2 + if (c.prop != 2) return "fail set" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateByTopLevelFun.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateByTopLevelFun.kt new file mode 100644 index 00000000000..5900d71c985 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateByTopLevelFun.kt @@ -0,0 +1,21 @@ +import kotlin.reflect.KProperty + +class Delegate { + var inner = 1 + operator fun getValue(t: Any?, p: KProperty<*>): Int = inner + operator fun setValue(t: Any?, p: KProperty<*>, i: Int) { inner = i } +} + +fun foo() = Delegate() + +class A { + var prop: Int by foo() +} + +fun box(): String { + val c = A() + if(c.prop != 1) return "fail get" + c.prop = 2 + if (c.prop != 2) return "fail set" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateByTopLevelProperty.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateByTopLevelProperty.kt new file mode 100644 index 00000000000..22f7b1b2ed3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateByTopLevelProperty.kt @@ -0,0 +1,21 @@ +import kotlin.reflect.KProperty + +class Delegate { + var inner = 1 + operator fun getValue(t: Any?, p: KProperty<*>): Int = inner + operator fun setValue(t: Any?, p: KProperty<*>, i: Int) { inner = i } +} + +val p = Delegate() + +class A { + var prop: Int by p +} + +fun box(): String { + val c = A() + if(c.prop != 1) return "fail get" + c.prop = 2 + if (c.prop != 2) return "fail set" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateForExtProperty.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateForExtProperty.kt new file mode 100644 index 00000000000..4eac9e2dc73 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateForExtProperty.kt @@ -0,0 +1,14 @@ +import kotlin.reflect.KProperty + +class Delegate { + operator fun getValue(t: A, p: KProperty<*>): Int = 1 +} + +val A.prop: Int by Delegate() + +class A { +} + +fun box(): String { + return if(A().prop == 1) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateForExtPropertyInClass.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateForExtPropertyInClass.kt new file mode 100644 index 00000000000..7cdaca652eb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateForExtPropertyInClass.kt @@ -0,0 +1,20 @@ +import kotlin.reflect.KProperty + +class Delegate { + operator fun getValue(t: F.A, p: KProperty<*>): Int = 1 +} + +class F { + val A.prop: Int by Delegate() + + class A { + } + + fun foo(): Int { + return A().prop + } +} + +fun box(): String { + return if(F().foo() == 1) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateWithPrivateSet.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateWithPrivateSet.kt new file mode 100644 index 00000000000..d44684bb4c8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/delegateWithPrivateSet.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME +// See KT-10107: 'Variable must be initialized' for delegate with private set + +class My { + var delegate: String by kotlin.properties.Delegates.notNull() + private set + + init { + delegate = "OK" + } +} + +fun box() = My().delegate diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/extensionDelegatesWithSameNames.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/extensionDelegatesWithSameNames.kt new file mode 100644 index 00000000000..ec5f37c0536 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/extensionDelegatesWithSameNames.kt @@ -0,0 +1,14 @@ +open class C + +object O : C() + +object K : C() + +class D(val value: String) { + operator fun getValue(thisRef: C, property: Any): String = value +} + +val O.prop by D("O") +val K.prop by D("K") + +fun box() = O.prop + K.prop diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/extensionPropertyAndExtensionGetValue.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/extensionPropertyAndExtensionGetValue.kt new file mode 100644 index 00000000000..1e796085d97 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/extensionPropertyAndExtensionGetValue.kt @@ -0,0 +1,13 @@ +class A(val o: String) + +interface I { + val k: String +} + +inline operator fun A.getValue(thisRef: I, property: Any): String = o + thisRef.k + +class B(override val k: String) : I + +val B.prop by A("O") + +fun box() = B("K").prop \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/genericDelegate.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/genericDelegate.kt new file mode 100644 index 00000000000..f1072a6c339 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/genericDelegate.kt @@ -0,0 +1,20 @@ +import kotlin.reflect.KProperty + +class Delegate(var inner: T) { + operator fun getValue(t: Any?, p: KProperty<*>): T = inner + operator fun setValue(t: Any?, p: KProperty<*>, i: T) { inner = i } +} + +class A { + inner class B { + var prop: Int by Delegate(1) + } +} + +fun box(): String { + val c = A().B() + if(c.prop != 1) return "fail get" + c.prop = 2 + if (c.prop != 2) return "fail set" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/getAsExtensionFun.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/getAsExtensionFun.kt new file mode 100644 index 00000000000..c08af8aeca2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/getAsExtensionFun.kt @@ -0,0 +1,14 @@ +import kotlin.reflect.KProperty + +class Delegate { +} + +operator fun Delegate.getValue(t: Any?, p: KProperty<*>): Int = 1 + +class A { + val prop: Int by Delegate() +} + +fun box(): String { + return if(A().prop == 1) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/getAsExtensionFunInClass.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/getAsExtensionFunInClass.kt new file mode 100644 index 00000000000..653c844066e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/getAsExtensionFunInClass.kt @@ -0,0 +1,13 @@ +import kotlin.reflect.KProperty + +class Delegate { +} + +class A { + operator fun Delegate.getValue(t: Any?, p: KProperty<*>): Int = 1 + val prop: Int by Delegate() +} + +fun box(): String { + return if(A().prop == 1) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/inClassVal.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/inClassVal.kt new file mode 100644 index 00000000000..0878fe18868 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/inClassVal.kt @@ -0,0 +1,13 @@ +import kotlin.reflect.KProperty + +class Delegate { + operator fun getValue(t: Any?, p: KProperty<*>): Int = 1 +} + +class A { + val prop: Int by Delegate() +} + +fun box(): String { + return if(A().prop == 1) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/inClassVar.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/inClassVar.kt new file mode 100644 index 00000000000..4541763a721 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/inClassVar.kt @@ -0,0 +1,19 @@ +import kotlin.reflect.KProperty + +class Delegate { + var inner = 1 + operator fun getValue(t: Any?, p: KProperty<*>): Int = inner + operator fun setValue(t: Any?, p: KProperty<*>, i: Int) { inner = i } +} + +class A { + var prop: Int by Delegate() +} + +fun box(): String { + val c = A() + if(c.prop != 1) return "fail get" + c.prop = 2 + if (c.prop != 2) return "fail set" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/inTrait.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/inTrait.kt new file mode 100644 index 00000000000..10a1746e561 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/inTrait.kt @@ -0,0 +1,17 @@ +import kotlin.reflect.KProperty + +class Delegate { + operator fun getValue(t: Any?, p: KProperty<*>): Int = 1 +} + +interface A { + val prop: Int +} + +class AImpl: A { + override val prop: Int by Delegate() +} + +fun box(): String { + return if(AImpl().prop == 1) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/inferredPropertyType.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/inferredPropertyType.kt new file mode 100644 index 00000000000..50d8ad91411 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/inferredPropertyType.kt @@ -0,0 +1,20 @@ +import kotlin.reflect.KProperty + +class Delegate(var inner: T) { + operator fun getValue(t: Any?, p: KProperty<*>): T = inner + operator fun setValue(t: Any?, p: KProperty<*>, i: T) { inner = i } +} + +class A { + inner class B { + var prop by Delegate(1) + } +} + +fun box(): String { + val c = A().B() + if(c.prop != 1) return "fail get" + c.prop = 2 + if (c.prop != 2) return "fail set" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/kt4138.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/kt4138.kt new file mode 100644 index 00000000000..f4535dd82e7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/kt4138.kt @@ -0,0 +1,37 @@ +import kotlin.reflect.KProperty + +class Delegate(var inner: T) { + operator fun getValue(t: Any?, p: KProperty<*>): T = inner + operator fun setValue(t: Any?, p: KProperty<*>, i: T) { inner = i } +} + + +class Foo (val f: Int) { + companion object { + val A: Foo by Delegate(Foo(11)) + var B: Foo by Delegate(Foo(11)) + } +} + +interface FooTrait { + companion object { + val A: Foo by Delegate(Foo(11)) + var B: Foo by Delegate(Foo(11)) + } +} + +fun box() : String { + if (Foo.A.f != 11) return "fail 1" + if (Foo.B.f != 11) return "fail 2" + + Foo.B = Foo(12) + if (Foo.B.f != 12) return "fail 3" + + if (FooTrait.A.f != 11) return "fail 4" + if (FooTrait.B.f != 11) return "fail 5" + + FooTrait.B = Foo(12) + if (FooTrait.B.f != 12) return "fail 6" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/kt6722.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/kt6722.kt new file mode 100644 index 00000000000..f680293e6dc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/kt6722.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME + +interface T { +} + +fun box(): String { + val a = "OK" + val t = object : T { + val foo by lazy { + a + } + } + return t.foo +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/kt9712.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/kt9712.kt new file mode 100644 index 00000000000..dd4f6cf1945 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/kt9712.kt @@ -0,0 +1,24 @@ +// WITH_RUNTIME + +import kotlin.properties.Delegates + +object X { + public var O: String + by Delegates.observable("O") { prop, old, new -> } + private set +} + +open class A { + public var K: String + by Delegates.observable("") { prop, old, new -> } + protected set +} + +class B : A() { + init { + K = "K" + } +} + +fun box(): String = + X.O + B().K diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/capturedLocalVal.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/capturedLocalVal.kt new file mode 100644 index 00000000000..52a0de0cd68 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/capturedLocalVal.kt @@ -0,0 +1,14 @@ +package foo + +import kotlin.reflect.KProperty + +inline fun run(f: () -> T) = f() + +class Delegate { + operator fun getValue(t: Any?, p: KProperty<*>): Int = 1 +} + +fun box(): String { + val prop: Int by Delegate() + return run { if (prop == 1) "OK" else "fail" } +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/capturedLocalValNoInline.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/capturedLocalValNoInline.kt new file mode 100644 index 00000000000..bb21f1e3b52 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/capturedLocalValNoInline.kt @@ -0,0 +1,14 @@ +package foo + +import kotlin.reflect.KProperty + +fun run(f: () -> T) = f() + +class Delegate { + operator fun getValue(t: Any?, p: KProperty<*>): Int = 1 +} + +fun box(): String { + val prop: Int by Delegate() + return run { if (prop == 1) "OK" else "fail" } +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/capturedLocalVar.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/capturedLocalVar.kt new file mode 100644 index 00000000000..d655e965ab1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/capturedLocalVar.kt @@ -0,0 +1,20 @@ +package foo + +import kotlin.reflect.KProperty + +inline fun run(f: () -> T) = f() + +class Delegate { + var inner = 1 + operator fun getValue(t: Any?, p: KProperty<*>): Int = inner + operator fun setValue(t: Any?, p: KProperty<*>, i: Int) { + inner = i + } +} + +fun box(): String { + var prop: Int by Delegate() + run { prop = 2 } + if (prop != 2) return "fail get" + return run { if (prop != 2) "fail set" else "OK" } +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/capturedLocalVarNoInline.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/capturedLocalVarNoInline.kt new file mode 100644 index 00000000000..8ac07a3f364 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/capturedLocalVarNoInline.kt @@ -0,0 +1,20 @@ +package foo + +import kotlin.reflect.KProperty + +fun run(f: () -> T) = f() + +class Delegate { + var inner = 1 + operator fun getValue(t: Any?, p: KProperty<*>): Int = inner + operator fun setValue(t: Any?, p: KProperty<*>, i: Int) { + inner = i + } +} + +fun box(): String { + var prop: Int by Delegate() + run { prop = 2 } + if (prop != 2) return "fail get" + return run { if (prop != 2) "fail set" else "OK" } +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/inlineGetValue.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/inlineGetValue.kt new file mode 100644 index 00000000000..80a60fd6e61 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/inlineGetValue.kt @@ -0,0 +1,12 @@ +package foo + +import kotlin.reflect.KProperty + +class Delegate { + inline operator fun getValue(t: Any?, p: KProperty<*>): String = p.name +} + +fun box(): String { + val OK: String by Delegate() + return OK +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/inlineOperators.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/inlineOperators.kt new file mode 100644 index 00000000000..98198d4acd4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/inlineOperators.kt @@ -0,0 +1,19 @@ +package foo + +import kotlin.reflect.KProperty + +class Delegate { + var inner = 1 + inline operator fun getValue(t: Any?, p: KProperty<*>): Int = inner + inline operator fun setValue(t: Any?, p: KProperty<*>, i: Int) { + inner = i + } +} + +fun box(): String { + var prop: Int by Delegate() + if (prop != 1) return "fail get" + prop = 2 + if (prop != 2) return "fail set" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/kt12891.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/kt12891.kt new file mode 100644 index 00000000000..683c4fca841 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/kt12891.kt @@ -0,0 +1,5 @@ +//WITH_RUNTIME +fun box(): String { + val x by lazy { "OK" } + return x +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/kt13557.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/kt13557.kt new file mode 100644 index 00000000000..dd49cb336dd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/kt13557.kt @@ -0,0 +1,14 @@ +//WITH_REFLECT + +import kotlin.properties.Delegates + +fun box(): String { + var foo: String by Delegates.notNull(); + + object { + fun baz() { + foo = "OK" + } + }.baz() + return foo +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/localVal.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/localVal.kt new file mode 100644 index 00000000000..cd3f7178453 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/localVal.kt @@ -0,0 +1,12 @@ +package foo + +import kotlin.reflect.KProperty + +class Delegate { + operator fun getValue(t: Any?, p: KProperty<*>): Int = 1 +} + +fun box(): String { + val prop: Int by Delegate() + return if (prop == 1) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/localValNoExplicitType.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/localValNoExplicitType.kt new file mode 100644 index 00000000000..20e86275732 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/localValNoExplicitType.kt @@ -0,0 +1,12 @@ +package foo + +import kotlin.reflect.KProperty + +class Delegate { + operator fun getValue(t: Any?, p: KProperty<*>): Int = 1 +} + +fun box(): String { + val prop by Delegate() + return if (prop == 1) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/localVar.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/localVar.kt new file mode 100644 index 00000000000..606bc60c871 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/localVar.kt @@ -0,0 +1,19 @@ +package foo + +import kotlin.reflect.KProperty + +class Delegate { + var inner = 1 + operator fun getValue(t: Any?, p: KProperty<*>): Int = inner + operator fun setValue(t: Any?, p: KProperty<*>, i: Int) { + inner = i + } +} + +fun box(): String { + var prop: Int by Delegate() + if (prop != 1) return "fail get" + prop = 2 + if (prop != 2) return "fail set" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/localVarNoExplicitType.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/localVarNoExplicitType.kt new file mode 100644 index 00000000000..b9e51893775 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/local/localVarNoExplicitType.kt @@ -0,0 +1,19 @@ +package foo + +import kotlin.reflect.KProperty + +class Delegate { + var inner = 1 + operator fun getValue(t: Any?, p: KProperty<*>): Int = inner + operator fun setValue(t: Any?, p: KProperty<*>, i: Int) { + inner = i + } +} + +fun box(): String { + var prop by Delegate() + if (prop != 1) return "fail get" + prop = 2 + if (prop != 2) return "fail set" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/privateSetterKPropertyIsNotMutable.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/privateSetterKPropertyIsNotMutable.kt new file mode 100644 index 00000000000..24c0e05c6c2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/privateSetterKPropertyIsNotMutable.kt @@ -0,0 +1,37 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.* + +object Delegate { + operator fun getValue(thiz: My, property: KProperty<*>): String { + if (property !is KMutableProperty<*>) return "Fail: property is not a KMutableProperty" + property as KMutableProperty1 + + try { + property.set(thiz, "") + return "Fail: property.set should cause IllegalCallableAccessException" + } + catch (e: IllegalCallableAccessException) { + // OK + } + + property.isAccessible = true + property.set(thiz, "") + + return "OK" + } + + operator fun setValue(thiz: My, property: KProperty<*>, value: String) { + } +} + +class My { + var delegate: String by Delegate + private set +} + +fun box() = My().delegate diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/privateVar.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/privateVar.kt new file mode 100644 index 00000000000..33faef3e3b1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/privateVar.kt @@ -0,0 +1,22 @@ +import kotlin.reflect.KProperty + +class Delegate { + var inner = 1 + operator fun getValue(t: Any?, p: KProperty<*>): Int = inner + operator fun setValue(t: Any?, p: KProperty<*>, i: Int) { inner = i } +} + +class A { + private var prop: Int by Delegate() + + fun test(): String { + if(prop != 1) return "fail get" + prop = 2 + if (prop != 2) return "fail set" + return "OK" + } +} + +fun box(): String { + return A().test() +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/propertyMetadataShouldBeCached.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/propertyMetadataShouldBeCached.kt new file mode 100644 index 00000000000..e6a328dd6a8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/propertyMetadataShouldBeCached.kt @@ -0,0 +1,50 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +import java.util.IdentityHashMap +import kotlin.reflect.KProperty + +class A { + var foo: Int by IntHandler + + companion object { + var bar: Any? by AnyHandler + } +} + +val baz: String by StringHandler + + + +val metadatas = IdentityHashMap, Unit>() + +fun record(p: KProperty<*>) = metadatas.put(p, Unit) + +object IntHandler { + operator fun getValue(t: Any?, p: KProperty<*>): Int { record(p); return 42 } + operator fun setValue(t: Any?, p: KProperty<*>, value: Int) { record(p) } +} + +object AnyHandler { + operator fun getValue(t: Any?, p: KProperty<*>): Any? { record(p); return 3.14 } + operator fun setValue(t: Any?, p: KProperty<*>, value: Any?) { record(p) } +} + +object StringHandler { + operator fun getValue(t: Any?, p: KProperty<*>): String { record(p); return p.name } + operator fun setValue(t: Any?, p: KProperty<*>, value: String) { record(p) } +} + +fun box(): String { + val a = A() + a.foo = 42 + a.foo = a.foo + baz.length + a.foo = 239 + A.bar = baz + a.foo + baz + A.bar + + if (metadatas.keys.size != 3) + return "Fail: only three instances of KProperty should have been created\n${metadatas.keys}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/protectedVarWithPrivateSet.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/protectedVarWithPrivateSet.kt new file mode 100644 index 00000000000..76bb953d48f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/protectedVarWithPrivateSet.kt @@ -0,0 +1,16 @@ +// WITH_RUNTIME + +import kotlin.properties.Delegates + +open class A { + protected var value: T by Delegates.notNull() + private set +} + +class B : A() + +fun box(): String { + B() + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/differentReceivers.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/differentReceivers.kt new file mode 100644 index 00000000000..990b7d63455 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/differentReceivers.kt @@ -0,0 +1,27 @@ +// WITH_RUNTIME + +import kotlin.test.* + +var log: String = "" + +class MyClass(val value: String) + +inline fun runLogged(entry: String, action: () -> T): T { + log += entry + return action() +} + +operator fun MyClass.provideDelegate(host: Any?, p: Any): String = + runLogged("tdf(${this.value});") { this.value } + +operator fun String.getValue(receiver: Any?, p: Any): String = + runLogged("get($this);") { this } + +val testO by runLogged("O;") { MyClass("O") } +val testK by runLogged("K;") { "K" } +val testOK = runLogged("OK;") { testO + testK } + +fun box(): String { + assertEquals("O;tdf(O);K;OK;get(O);get(K);", log) + return testOK +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/evaluationOrder.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/evaluationOrder.kt new file mode 100644 index 00000000000..c837b248604 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/evaluationOrder.kt @@ -0,0 +1,25 @@ +// WITH_RUNTIME + +import kotlin.test.* + +var log: String = "" + +inline fun runLogged(entry: String, action: () -> T): T { + log += entry + return action() +} + +operator fun String.provideDelegate(host: Any?, p: Any): String = + runLogged("tdf($this);") { this } + +operator fun String.getValue(receiver: Any?, p: Any): String = + runLogged("get($this);") { this } + +val testO by runLogged("O;") { "O" } +val testK by runLogged("K;") { "K" } +val testOK = runLogged("OK;") { testO + testK } + +fun box(): String { + assertEquals("O;tdf(O);K;tdf(K);OK;get(O);get(K);", log) + return testOK +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/evaluationOrderVar.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/evaluationOrderVar.kt new file mode 100644 index 00000000000..e31915c332d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/evaluationOrderVar.kt @@ -0,0 +1,38 @@ +// WITH_RUNTIME + +import kotlin.test.* + +var log: String = "" + +val dispatcher = hashMapOf() + +inline fun runLogged(entry: String, action: () -> T): T { + log += entry + return action() +} + +operator fun String.provideDelegate(host: Any?, p: Any): String { + dispatcher[this] = this + return runLogged("tdf($this);") { this } +} + +operator fun String.getValue(receiver: Any?, p: Any): String = + runLogged("get(${dispatcher[this]});") { dispatcher[this]!! } + +operator fun String.setValue(receiver: Any?, p: Any, newValue: String) { + dispatcher[this] = newValue + runLogged("set(${dispatcher[this]});") { dispatcher[this]!! } +} + +var testO by runLogged("K;") { "K" } +var testK by runLogged("O;") { "O" } +val testOK = runLogged("OK;") { + testO = "O" + testK = "K" + testO + testK +} + +fun box(): String { + assertEquals("K;tdf(K);O;tdf(O);OK;set(O);set(K);get(O);get(K);", log) + return testOK +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/extensionDelegated.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/extensionDelegated.kt new file mode 100644 index 00000000000..f44e553e7f7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/extensionDelegated.kt @@ -0,0 +1,16 @@ +import kotlin.reflect.KProperty + +var log = "" + +class UserDataProperty(val key: String) { + operator fun getValue(thisRef: R, desc: KProperty<*>) = thisRef.toString() + key + + operator fun setValue(thisRef: R, desc: KProperty<*>, value: String?) { log += "set"} +} + + +var String.calc: String by UserDataProperty("K") + +fun box(): String { + return "O".calc +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/generic.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/generic.kt new file mode 100644 index 00000000000..8e6af346f90 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/generic.kt @@ -0,0 +1,31 @@ +// WITH_RUNTIME + +import kotlin.test.* + +var log: String = "" + +open class MyClass(val value: String) { + override fun toString(): String { + return value + } +} + +inline fun runLogged(entry: String, action: () -> T): T { + log += entry + return action() +} + +operator fun T.provideDelegate(host: Any?, p: Any): T = + runLogged("tdf(${this.value});") { this } + +operator fun T.getValue(receiver: Any?, p: Any): T = + runLogged("get($this);") { this } + +val testO by runLogged("O;") { MyClass("O") } +val testK by runLogged("K;") { "K" } +val testOK = runLogged("OK;") { testO.value + testK } + +fun box(): String { + assertEquals("O;tdf(O);K;OK;get(O);get(K);", log) + return testOK +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/hostCheck.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/hostCheck.kt new file mode 100644 index 00000000000..788f19e57d0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/hostCheck.kt @@ -0,0 +1,14 @@ +import kotlin.reflect.KProperty + +class Delegate(val value: String) { + operator fun provideDelegate(instance: A, property: KProperty<*>): Delegate = Delegate(instance.value) + operator fun getValue(instance: Any?, property: KProperty<*>) = value +} + +class A(val value: String) { + val result: String by Delegate("Fail") +} + +fun box(): String { + return A("OK").result +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/inClass.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/inClass.kt new file mode 100644 index 00000000000..e1456a8bd0f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/inClass.kt @@ -0,0 +1,29 @@ +// WITH_RUNTIME + +import kotlin.test.* + +var log: String = "" + +inline fun runLogged(entry: String, action: () -> T): T { + log += entry + return action() +} + +operator fun String.provideDelegate(host: Any?, p: Any): String = + runLogged("tdf($this);") { this } + +operator fun String.getValue(receiver: Any?, p: Any): String = + runLogged("get($this);") { this } + +class Test { + val testO by runLogged("O;") { "O" } + val testK by runLogged("K;") { "K" } + val testOK = runLogged("OK;") { testO + testK } +} + +fun box(): String { + assertEquals("", log) + val test = Test() + assertEquals("O;tdf(O);K;tdf(K);OK;get(O);get(K);", log) + return test.testOK +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/inlineProvideDelegate.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/inlineProvideDelegate.kt new file mode 100644 index 00000000000..3ce685006b0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/inlineProvideDelegate.kt @@ -0,0 +1,25 @@ +// WITH_RUNTIME + +import kotlin.test.* + +var log: String = "" + +inline fun runLogged(entry: String, action: () -> T): T { + log += entry + return action() +} + +inline operator fun String.provideDelegate(host: Any?, p: Any): String = + runLogged("tdf($this);") { this } + +operator fun String.getValue(receiver: Any?, p: Any): String = + runLogged("get($this);") { this } + +val testO by runLogged("O;") { "O" } +val testK by runLogged("K;") { "K" } +val testOK = runLogged("OK;") { testO + testK } + +fun box(): String { + assertEquals("O;tdf(O);K;tdf(K);OK;get(O);get(K);", log) + return testOK +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/jvmStaticInObject.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/jvmStaticInObject.kt new file mode 100644 index 00000000000..4ed34e5382c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/jvmStaticInObject.kt @@ -0,0 +1,31 @@ +// WITH_RUNTIME +// IGNORE_BACKEND: JS, NATIVE + +import kotlin.test.* + +var log: String = "" + +inline fun runLogged(entry: String, action: () -> T): T { + log += entry + return action() +} + +operator fun String.provideDelegate(host: Any?, p: Any): String = + runLogged("tdf($this);") { this } + +operator fun String.getValue(receiver: Any?, p: Any): String = + runLogged("get($this);") { this } + +object Test { + fun foo() {} + @JvmStatic val testO by runLogged("O;") { "O" } + @JvmStatic val testK by runLogged("K;") { "K" } + @JvmStatic val testOK = runLogged("OK;") { testO + testK } +} + +fun box(): String { + assertEquals("", log) + Test.foo() + assertEquals("O;tdf(O);K;tdf(K);OK;get(O);get(K);", log) + return Test.testOK +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/kt15437.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/kt15437.kt new file mode 100644 index 00000000000..85d54e3cc18 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/kt15437.kt @@ -0,0 +1,12 @@ +import kotlin.reflect.KProperty + +class Delegate { + operator fun provideDelegate(instance: Any?, property: KProperty<*>): Delegate = this + operator fun getValue(instance: Any?, property: KProperty<*>) = "OK" +} + +val result: String by Delegate() + +fun box(): String { + return result +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/local.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/local.kt new file mode 100644 index 00000000000..e010f9f1242 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/local.kt @@ -0,0 +1,25 @@ +// WITH_RUNTIME + +import kotlin.test.* + +var log: String = "" + +inline fun runLogged(entry: String, action: () -> T): T { + log += entry + return action() +} + +operator fun String.provideDelegate(host: Any?, p: Any): String = + runLogged("tdf($this);") { this } + +operator fun String.getValue(receiver: Any?, p: Any): String = + runLogged("get($this);") { this } + +fun box(): String { + val testO by runLogged("O;") { "O" } + val testK by runLogged("K;") { "K" } + val testOK = runLogged("OK;") { testO + testK } + + assertEquals("O;tdf(O);K;tdf(K);OK;get(O);get(K);", log) + return testOK +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/localCaptured.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/localCaptured.kt new file mode 100644 index 00000000000..1018b841950 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/localCaptured.kt @@ -0,0 +1,25 @@ +// WITH_RUNTIME + +import kotlin.test.* + +var log: String = "" + +fun runLogged(entry: String, action: () -> T): T { + log += entry + return action() +} + +operator fun String.provideDelegate(host: Any?, p: Any): String = + runLogged("tdf($this);") { this } + +operator fun String.getValue(receiver: Any?, p: Any): String = + runLogged("get($this);") { this } + +fun box(): String { + val testO by runLogged("O;") { "O" } + val testK by runLogged("K;") { "K" } + val testOK = runLogged("OK;") { testO + testK } + + assertEquals("O;tdf(O);K;tdf(K);OK;get(O);get(K);", log) + return testOK +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/localDifferentReceivers.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/localDifferentReceivers.kt new file mode 100644 index 00000000000..387236a5640 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/localDifferentReceivers.kt @@ -0,0 +1,33 @@ +// WITH_RUNTIME + +import kotlin.test.* + +var log: String = "" + +class MyClass(val value: String) + +fun runLogged(entry: String, action: () -> String): String { + log += entry + return action() +} + +fun runLogged2(entry: String, action: () -> MyClass): MyClass { + log += entry + return action() +} + +operator fun MyClass.provideDelegate(host: Any?, p: Any): String = + runLogged("tdf(${this.value});") { this.value } + +operator fun String.getValue(receiver: Any?, p: Any): String = + runLogged("get($this);") { this } + + +fun box(): String { + val testO by runLogged2("O;") { MyClass("O") } + val testK by runLogged("K;") { "K" } + val testOK = runLogged("OK;") { testO + testK } + + assertEquals("O;tdf(O);K;OK;get(O);get(K);", log) + return testOK +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/memberExtension.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/memberExtension.kt new file mode 100644 index 00000000000..7cfa5f86b0c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/memberExtension.kt @@ -0,0 +1,15 @@ +// WITH_RUNTIME + +object Host { + class StringDelegate(val s: String) { + operator fun getValue(receiver: String, p: Any) = receiver + s + } + + operator fun String.provideDelegate(host: Any?, p: Any) = StringDelegate(this) + + val String.plusK by "K" + + val ok = "O".plusK +} + +fun box(): String = Host.ok \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/propertyMetadata.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/propertyMetadata.kt new file mode 100644 index 00000000000..549b1b249e4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/provideDelegate/propertyMetadata.kt @@ -0,0 +1,26 @@ +// WITH_RUNTIME + +import kotlin.test.* +import kotlin.reflect.KProperty + +var log: String = "" + +inline fun runLogged(entry: String, action: () -> T): T { + log += entry + return action() +} + +operator fun String.provideDelegate(host: Any?, p: KProperty<*>): String = + if (p.name == this) runLogged("tdf($this);") { this } else "fail 1" + +operator fun String.getValue(receiver: Any?, p: KProperty<*>): String = + if (p.name == this) runLogged("get($this);") { this } else "fail 2" + +val O by runLogged("O;") { "O" } +val K by runLogged("K;") { "K" } +val OK = runLogged("OK;") { O + K } + +fun box(): String { + assertEquals("O;tdf(O);K;tdf(K);OK;get(O);get(K);", log) + return OK +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/setAsExtensionFun.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/setAsExtensionFun.kt new file mode 100644 index 00000000000..69924d135ff --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/setAsExtensionFun.kt @@ -0,0 +1,20 @@ +import kotlin.reflect.KProperty + +class Delegate { + var inner = 1 + operator fun getValue(t: Any?, p: KProperty<*>): Int = inner +} + +operator fun Delegate.setValue(t: Any?, p: KProperty<*>, i: Int) { inner = i } + +class A { + var prop: Int by Delegate() +} + +fun box(): String { + val c = A() + if(c.prop != 1) return "fail get" + c.prop = 2 + if (c.prop != 2) return "fail set" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/setAsExtensionFunInClass.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/setAsExtensionFunInClass.kt new file mode 100644 index 00000000000..ef2ddccf0f6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/setAsExtensionFunInClass.kt @@ -0,0 +1,20 @@ +import kotlin.reflect.KProperty + +class Delegate { + var inner = 1 + operator fun getValue(t: Any?, p: KProperty<*>): Int = inner +} + +class A { + operator fun Delegate.setValue(t: Any?, p: KProperty<*>, i: Int) { inner = i } + + var prop: Int by Delegate() +} + +fun box(): String { + val c = A() + if(c.prop != 1) return "fail get" + c.prop = 2 + if (c.prop != 2) return "fail set" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/stackOverflowOnCallFromGetValue.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/stackOverflowOnCallFromGetValue.kt new file mode 100644 index 00000000000..6e1dd50372e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/stackOverflowOnCallFromGetValue.kt @@ -0,0 +1,57 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FULL_JDK + +import java.lang.reflect.InvocationTargetException +import kotlin.reflect.* + +object Delegate { + operator fun getValue(t: Any?, p: KProperty<*>): String { + (p as? KProperty0)?.get() + (p as? KProperty1)?.get(O) + (p as? KProperty2)?.get(O, O) + return "Fail" + } + + operator fun setValue(t: Any?, p: KProperty<*>, v: String) { + (p as? KMutableProperty0)?.set(v) + (p as? KMutableProperty1)?.set(O, v) + (p as? KMutableProperty2)?.set(O, O, v) + } +} + +var topLevel: String by Delegate +object O { + var member: String by Delegate + var O.memExt: String by Delegate +} + +fun check(lambda: () -> Unit) { + try { + lambda() + } catch (e: Throwable) { + if (e !is InvocationTargetException && e !is StackOverflowError) { + throw RuntimeException("The current implementation uses reflection to get the value of the property," + + "so either InvocationTargetException or StackOverflowError should have happened", + e) + } + return + } + throw AssertionError("Getting the property value with .get() from getValue() or setting it with .set() in setValue() " + + "is effectively an endless recursion and should fail") +} + +fun box(): String { + check { topLevel } + check { topLevel = "" } + check { O.member } + check { O.member = "" } + with (O) { + check { O.memExt } + check { O.memExt = "" } + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/topLevelVal.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/topLevelVal.kt new file mode 100644 index 00000000000..e28913fabbe --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/topLevelVal.kt @@ -0,0 +1,11 @@ +import kotlin.reflect.KProperty + +class Delegate { + operator fun getValue(t: Any?, p: KProperty<*>): Int = 1 +} + +val prop: Int by Delegate() + +fun box(): String { + return if(prop == 1) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/topLevelVar.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/topLevelVar.kt new file mode 100644 index 00000000000..688405e32de --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/topLevelVar.kt @@ -0,0 +1,16 @@ +import kotlin.reflect.KProperty + +class Delegate { + var inner = 1 + operator fun getValue(t: Any?, p: KProperty<*>): Int = inner + operator fun setValue(t: Any?, p: KProperty<*>, i: Int) { inner = i } +} + +var prop: Int by Delegate() + +fun box(): String { + if(prop != 1) return "fail get" + prop = 2 + if (prop != 2) return "fail set" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/twoPropByOneDelegete.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/twoPropByOneDelegete.kt new file mode 100644 index 00000000000..d73aadaf604 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/twoPropByOneDelegete.kt @@ -0,0 +1,22 @@ +import kotlin.reflect.KProperty + +class Delegate(val f: (T) -> Int) { + operator fun getValue(t: T, p: KProperty<*>): Int = f(t) +} + +val p = Delegate { t -> t.foo() } + +class A(val i: Int) { + val prop: Int by p + + fun foo(): Int { + return i + } +} + +fun box(): String { + if(A(1).prop != 1) return "fail get1" + if(A(10).prop != 10) return "fail get2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/useKPropertyLater.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/useKPropertyLater.kt new file mode 100644 index 00000000000..f457e44dafc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/useKPropertyLater.kt @@ -0,0 +1,45 @@ +// WITH_REFLECT +// TODO: replace with WITH_RUNTIME once KT-11316 is fixed + +import kotlin.reflect.* + +val properties = HashSet>() + +object Delegate { + operator fun getValue(t: Any?, p: KProperty<*>): String { + properties.add(p) + return "" + } + + operator fun setValue(t: Any?, p: KProperty<*>, v: String) { + properties.add(p) + } +} + +var topLevel: String by Delegate +object O { + var member: String by Delegate + var O.memExt: String by Delegate +} + +fun box(): String { + topLevel = "" + O.member = "" + with (O) { + O.memExt = "" + } + + for (p in HashSet(properties)) { + // None of these should fail + + (p as? KProperty0)?.get() + (p as? KProperty1)?.get(O) + (p as? KProperty2)?.get(O, O) + + (p as? KMutableProperty0)?.set("") + (p as? KMutableProperty1)?.set(O, "") + (p as? KMutableProperty2)?.set(O, O, "") + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/useReflectionOnKProperty.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/useReflectionOnKProperty.kt new file mode 100644 index 00000000000..ac69d29fe35 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/useReflectionOnKProperty.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KProperty + +class Delegate { + operator fun getValue(t: Any?, p: KProperty<*>): String { + p.parameters + p.returnType + p.annotations + return p.toString() + } +} + +val prop: String by Delegate() + +fun box() = if (prop == "val prop: kotlin.String") "OK" else "Fail: $prop" diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/valInInnerClass.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/valInInnerClass.kt new file mode 100644 index 00000000000..43cda384acc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/valInInnerClass.kt @@ -0,0 +1,15 @@ +import kotlin.reflect.KProperty + +class Delegate { + operator fun getValue(t: Any?, p: KProperty<*>): Int = 1 +} + +class A { + inner class B { + val prop: Int by Delegate() + } +} + +fun box(): String { + return if(A().B().prop == 1) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegatedProperty/varInInnerClass.kt b/backend.native/tests/external/codegen/blackbox/delegatedProperty/varInInnerClass.kt new file mode 100644 index 00000000000..4b99bb19003 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegatedProperty/varInInnerClass.kt @@ -0,0 +1,21 @@ +import kotlin.reflect.KProperty + +class Delegate { + var inner = 1 + operator fun getValue(t: Any?, p: KProperty<*>): Int = inner + operator fun setValue(t: Any?, p: KProperty<*>, i: Int) { inner = i } +} + +class A { + inner class B { + var prop: Int by Delegate() + } +} + +fun box(): String { + val c = A().B() + if(c.prop != 1) return "fail get" + c.prop = 2 + if (c.prop != 2) return "fail set" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/delegation/delegationToVal.kt b/backend.native/tests/external/codegen/blackbox/delegation/delegationToVal.kt new file mode 100644 index 00000000000..4abbca2775a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegation/delegationToVal.kt @@ -0,0 +1,49 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +interface IActing { + fun act(): String +} + +class CActing(val value: String = "OK") : IActing { + override fun act(): String = value +} + +// final so no need in delegate field +class Test(val acting: CActing = CActing()) : IActing by acting { +} + +// even if open so we don't need delegate field +open class Test2(open val acting: CActing = CActing()) : IActing by acting { +} + +// even if open the backing field is final, so we don't need delegate field +class Test3() : Test2() { + override val acting = CActing("OKOK") +} + +fun box(): String { + try { + Test::class.java.getDeclaredField("\$\$delegate_0") + return "\$\$delegate_0 field generated for class Test but should not" + } + catch (e: NoSuchFieldException) { + // ok + } + + try { + Test2::class.java.getDeclaredField("\$\$delegate_0") + return "\$\$delegate_0 field generated for class Test but should not" + } + catch (e: NoSuchFieldException) { + // ok + } + + if (Test3().acting.act() != "OKOK") return "Fail Test3" + + val test = Test() + return test.act() +} diff --git a/backend.native/tests/external/codegen/blackbox/delegation/kt8154.kt b/backend.native/tests/external/codegen/blackbox/delegation/kt8154.kt new file mode 100644 index 00000000000..86550e49f60 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/delegation/kt8154.kt @@ -0,0 +1,19 @@ +interface A { + fun foo(): T +} + +interface B : A + +class BImpl(a: A) : B, A by a + +fun box(): String { + val b: B = BImpl(object : A { + override fun foo() = "OK" + }) + + if (b.foo() != "OK") return "fail 1" + + val a: A = b + + return a.foo() +} diff --git a/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/extensionComponents.kt b/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/extensionComponents.kt new file mode 100644 index 00000000000..201e2cb3a60 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/extensionComponents.kt @@ -0,0 +1,21 @@ +class A(val x: String, val y: String, val z: T) + +fun foo(a: A, block: (A) -> String): String = block(a) + +operator fun A<*>.component1() = x + +object B { + operator fun A<*>.component2() = y +} + +fun B.bar(): String { + + operator fun A.component3() = z + + val x = foo(A("O", "K", 123)) { (x, y, z) -> x + y + z.toString() } + if (x != "OK123") return "fail 1: $x" + + return "OK" +} + +fun box() = B.bar() diff --git a/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/generic.kt b/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/generic.kt new file mode 100644 index 00000000000..4dadddb91cd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/generic.kt @@ -0,0 +1,11 @@ +data class A(val x: T, val y: F) + +fun foo(a: A, block: (A) -> String) = block(a) + +fun box(): String { + val x = foo(A("OK", 1)) { (x, y) -> x + (y.toString()) } + + if (x != "OK1") return "fail1: $x" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/inline.kt b/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/inline.kt new file mode 100644 index 00000000000..6835b91f21c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/inline.kt @@ -0,0 +1,5 @@ +data class A(val x: String, val y: String) + +inline fun foo(a: A, block: (A) -> String): String = block(a) + +fun box() = foo(A("O", "K")) { (x, y) -> x + y } diff --git a/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/otherParameters.kt b/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/otherParameters.kt new file mode 100644 index 00000000000..f973aca1710 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/otherParameters.kt @@ -0,0 +1,11 @@ +data class A(val x: String, val y: String) + +fun foo(a: A, block: (Int, A, String) -> String): String = block(1, a, "#") + +fun box(): String { + val x = foo(A("O", "K")) { i, (x, y), v -> i.toString() + x + y + v } + + if (x != "1OK#") return "fail 1: $x" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/simple.kt b/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/simple.kt new file mode 100644 index 00000000000..50523e3fec4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/simple.kt @@ -0,0 +1,5 @@ +data class A(val x: String, val y: String) + +fun foo(a: A, block: (A) -> String): String = block(a) + +fun box() = foo(A("O", "K")) { (x, y) -> x + y } diff --git a/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/stdlibUsages.kt b/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/stdlibUsages.kt new file mode 100644 index 00000000000..fe527e1237d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/stdlibUsages.kt @@ -0,0 +1,16 @@ +// WITH_RUNTIME + +fun box(): String { + val r1 = listOf("O", "K", "fail").let { + (x, y) -> x + y + } + + + if (r1 != "OK") return "fail 1: $r1" + + val r2 = listOf(Pair("O", "K")).map { (x, y) -> x + y }[0] + + if (r2 != "OK") return "fail 2: $r2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/underscoreNames.kt b/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/underscoreNames.kt new file mode 100644 index 00000000000..8db07f7778e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/underscoreNames.kt @@ -0,0 +1,9 @@ +class A { + operator fun component1() = "O" + operator fun component2(): String = throw RuntimeException("fail 0") + operator fun component3() = "K" +} + +fun foo(a: A, block: (A) -> String): String = block(a) + +fun box() = foo(A()) { (x, _, y) -> x + y } diff --git a/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/withIndexed.kt b/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/withIndexed.kt new file mode 100644 index 00000000000..13280feb86e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/destructuringDeclInLambdaParam/withIndexed.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME +data class Station( + val id: String?, + val name: String, + val distance: Int) + +fun box(): String { + var result = "" + // See KT-14399 + listOf(Station("O", "K", 56)).forEachIndexed { i, (id, name, distance) -> result += "$id$name$distance" } + if (result != "OK56") return "fail: $result" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/inference/kt6176.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/inference/kt6176.kt new file mode 100644 index 00000000000..15a7a2e94e2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/inference/kt6176.kt @@ -0,0 +1,25 @@ +// !DIAGNOSTICS: -DEBUG_INFO_SMARTCAST + +fun foo(f: () -> R): R = f() + +fun some(v: T?, b: T): T { + return foo { + if (v != null) { + v + } + else { + b + } + } +} + +fun some1(v: T?, b: T): T { + return foo { if (v != null) v else b } +} + +fun box() = when { + some(1, 2) != 1 -> "fail 1" + some(null, 2) != 2 -> "fail 2" + some1(1, 2) != 1 -> "fail 3" + else -> "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/inference/kt6176.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/inference/kt6176.txt new file mode 100644 index 00000000000..ebfdf25004c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/inference/kt6176.txt @@ -0,0 +1,6 @@ +package + +public fun box(): kotlin.String +public fun foo(/*0*/ f: () -> R): R +public fun some(/*0*/ v: T?, /*1*/ b: T): T +public fun some1(/*0*/ v: T?, /*1*/ b: T): T diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObject1.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObject1.kt new file mode 100644 index 00000000000..5f7fbce55f9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObject1.kt @@ -0,0 +1,8 @@ +class A { + companion object { + operator fun invoke(i: Int) = i + } +} + +fun box() = if (A(42) == 42) "OK" else "fail" + diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObject1.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObject1.txt new file mode 100644 index 00000000000..29670b42fcb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObject1.txt @@ -0,0 +1,18 @@ +package + +public fun box(): kotlin.String + +public final class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public companion object Companion { + private constructor Companion() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final operator fun invoke(/*0*/ i: kotlin.Int): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObject2.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObject2.kt new file mode 100644 index 00000000000..b808ed09f6a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObject2.kt @@ -0,0 +1,11 @@ +interface B + +operator fun B.invoke(i: Int) = i + +class A { + companion object: B { + } +} + +fun box() = if (A(42) == 42) "OK" else "fail" + diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObject2.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObject2.txt new file mode 100644 index 00000000000..6ab8e9be9be --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObject2.txt @@ -0,0 +1,24 @@ +package + +public fun box(): kotlin.String +public operator fun B.invoke(/*0*/ i: kotlin.Int): kotlin.Int + +public final class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public companion object Companion : B { + private constructor Companion() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public interface B { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObjectOfNestedClass1.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObjectOfNestedClass1.kt new file mode 100644 index 00000000000..dcc924a9ba8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObjectOfNestedClass1.kt @@ -0,0 +1,9 @@ +class A { + class Nested { + companion object { + operator fun invoke(i: Int) = i + } + } +} + +fun box() = if (A.Nested(42) == 42) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObjectOfNestedClass1.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObjectOfNestedClass1.txt new file mode 100644 index 00000000000..4722c798bb3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObjectOfNestedClass1.txt @@ -0,0 +1,25 @@ +package + +public fun box(): kotlin.String + +public final class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public final class Nested { + public constructor Nested() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public companion object Companion { + private constructor Companion() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final operator fun invoke(/*0*/ i: kotlin.Int): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObjectOfNestedClass2.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObjectOfNestedClass2.kt new file mode 100644 index 00000000000..85b73084d1a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObjectOfNestedClass2.kt @@ -0,0 +1,11 @@ +import A.Nested + +class A { + class Nested { + companion object { + operator fun invoke(i: Int) = i + } + } +} + +fun box() = if (Nested(42) == 42) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObjectOfNestedClass2.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObjectOfNestedClass2.txt new file mode 100644 index 00000000000..4722c798bb3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnClassObjectOfNestedClass2.txt @@ -0,0 +1,25 @@ +package + +public fun box(): kotlin.String + +public final class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public final class Nested { + public constructor Nested() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public companion object Companion { + private constructor Companion() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final operator fun invoke(/*0*/ i: kotlin.Int): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnEnum1.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnEnum1.kt new file mode 100644 index 00000000000..6491d8e0cc9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnEnum1.kt @@ -0,0 +1,8 @@ +enum class A { + ONE, + TWO; + + operator fun invoke(i: Int) = i +} + +fun box() = if (A.ONE(42) == 42) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnEnum1.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnEnum1.txt new file mode 100644 index 00000000000..98f250eefb7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnEnum1.txt @@ -0,0 +1,25 @@ +package + +public fun box(): kotlin.String + +public final enum class A : kotlin.Enum { + enum entry ONE + + enum entry TWO + + private constructor A() + public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit + public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class! + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final operator fun invoke(/*0*/ i: kotlin.Int): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): A + public final /*synthesized*/ fun values(): kotlin.Array +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnEnum2.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnEnum2.kt new file mode 100644 index 00000000000..95eb4b9c827 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnEnum2.kt @@ -0,0 +1,8 @@ +enum class A { + ONE, + TWO +} + +operator fun A.invoke(i: Int) = i + +fun box() = if (A.ONE(42) == 42) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnEnum2.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnEnum2.txt new file mode 100644 index 00000000000..0547a5bfbde --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnEnum2.txt @@ -0,0 +1,25 @@ +package + +public fun box(): kotlin.String +public operator fun A.invoke(/*0*/ i: kotlin.Int): kotlin.Int + +public final enum class A : kotlin.Enum { + enum entry ONE + + enum entry TWO + + private constructor A() + public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit + public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class! + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): A + public final /*synthesized*/ fun values(): kotlin.Array +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnImportedEnum1.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnImportedEnum1.kt new file mode 100644 index 00000000000..d627dad85a8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnImportedEnum1.kt @@ -0,0 +1,10 @@ +import A.ONE + +enum class A { + ONE, + TWO; + + operator fun invoke(i: Int) = i +} + +fun box() = if (ONE(42) == 42) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnImportedEnum1.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnImportedEnum1.txt new file mode 100644 index 00000000000..98f250eefb7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnImportedEnum1.txt @@ -0,0 +1,25 @@ +package + +public fun box(): kotlin.String + +public final enum class A : kotlin.Enum { + enum entry ONE + + enum entry TWO + + private constructor A() + public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit + public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class! + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final operator fun invoke(/*0*/ i: kotlin.Int): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): A + public final /*synthesized*/ fun values(): kotlin.Array +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnImportedEnum2.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnImportedEnum2.kt new file mode 100644 index 00000000000..53ecfc65908 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnImportedEnum2.kt @@ -0,0 +1,10 @@ +import A.ONE + +enum class A { + ONE, + TWO +} + +operator fun A.invoke(i: Int) = i + +fun box() = if (ONE(42) == 42) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnImportedEnum2.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnImportedEnum2.txt new file mode 100644 index 00000000000..0547a5bfbde --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnImportedEnum2.txt @@ -0,0 +1,25 @@ +package + +public fun box(): kotlin.String +public operator fun A.invoke(/*0*/ i: kotlin.Int): kotlin.Int + +public final enum class A : kotlin.Enum { + enum entry ONE + + enum entry TWO + + private constructor A() + public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: A): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit + public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class! + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): A + public final /*synthesized*/ fun values(): kotlin.Array +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnObject1.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnObject1.kt new file mode 100644 index 00000000000..e14c1acefc4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnObject1.kt @@ -0,0 +1,5 @@ +object A + +operator fun A.invoke(i: Int) = i + +fun box() = if (A(42) == 42) "OK" else "fail" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnObject1.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnObject1.txt new file mode 100644 index 00000000000..cb0f049e350 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnObject1.txt @@ -0,0 +1,11 @@ +package + +public fun box(): kotlin.String +public operator fun A.invoke(/*0*/ i: kotlin.Int): kotlin.Int + +public object A { + private constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnObject2.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnObject2.kt new file mode 100644 index 00000000000..fc16215881c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnObject2.kt @@ -0,0 +1,5 @@ +object A { + operator fun invoke(i: Int) = i +} + +fun box() = if (A(42) == 42) "OK" else "fail" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnObject2.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnObject2.txt new file mode 100644 index 00000000000..a0046e7528d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/invoke/onObjects/invokeOnObject2.txt @@ -0,0 +1,11 @@ +package + +public fun box(): kotlin.String + +public object A { + private constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final operator fun invoke(/*0*/ i: kotlin.Int): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/defaultArgs.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/defaultArgs.kt new file mode 100644 index 00000000000..77551daaaf2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/defaultArgs.kt @@ -0,0 +1,15 @@ +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun test(x : Int = 0, e : Any = "a") { + if (!e.equals("a")) { + throw IllegalArgumentException() + } + if (x > 0) { + test(x - 1) + } +} + +fun box() : String { + test(100000) + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/defaultArgs.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/defaultArgs.txt new file mode 100644 index 00000000000..1e8d7ae0b64 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/defaultArgs.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun test(/*0*/ x: kotlin.Int = ..., /*1*/ e: kotlin.Any = ...): kotlin.Unit diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/defaultArgsOverridden.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/defaultArgsOverridden.kt new file mode 100644 index 00000000000..2f924b56908 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/defaultArgsOverridden.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +open class A { + open fun foo(s: String = "OK") = s +} + +class B : A() { + override tailrec fun foo(s: String): String { + return if (s == "OK") s else foo() + } +} + +fun box() = B().foo("FAIL") \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/defaultArgsOverridden.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/defaultArgsOverridden.txt new file mode 100644 index 00000000000..f5a8d3fb277 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/defaultArgsOverridden.txt @@ -0,0 +1,19 @@ +package + +public fun box(): kotlin.String + +public open class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun foo(/*0*/ s: kotlin.String = ...): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class B : A { + public constructor B() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open tailrec override /*1*/ fun foo(/*0*/ s: kotlin.String = ...): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/extensionTailCall.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/extensionTailCall.kt new file mode 100644 index 00000000000..e9873fc4a14 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/extensionTailCall.kt @@ -0,0 +1,13 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun Int.foo(x: Int) { + if (x == 0) return + return 1.foo(x - 1) +} + +fun box(): String { + 1.foo(1000000) + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/extensionTailCall.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/extensionTailCall.txt new file mode 100644 index 00000000000..48175789377 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/extensionTailCall.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun kotlin.Int.foo(/*0*/ x: kotlin.Int): kotlin.Unit diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithNoTails.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithNoTails.kt new file mode 100644 index 00000000000..15eb0203244 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithNoTails.kt @@ -0,0 +1,11 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun noTails() { + // nothing here +} + +fun box(): String { + noTails() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithNoTails.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithNoTails.txt new file mode 100644 index 00000000000..7ecae67b1cb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithNoTails.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun noTails(): kotlin.Unit diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithNonTailRecursions.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithNonTailRecursions.kt new file mode 100644 index 00000000000..c6b15a3234d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithNonTailRecursions.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun badTails(x : Int) : Int { + if (x < 50 && x != 10 && x > 0) { + return 1 + badTails(x - 1) + } + else if (x == 10) { + @Suppress("NON_TAIL_RECURSIVE_CALL") + return 1 + badTails(x - 1) + } else if (x >= 50) { + return badTails(x - 1) + } + return 0 +} + +fun box(): String { + badTails(1000000) + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithNonTailRecursions.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithNonTailRecursions.txt new file mode 100644 index 00000000000..34acf2c57af --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithNonTailRecursions.txt @@ -0,0 +1,4 @@ +package + +public tailrec fun badTails(/*0*/ x: kotlin.Int): kotlin.Int +public fun box(): kotlin.String diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithoutAnnotation.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithoutAnnotation.kt new file mode 100644 index 00000000000..06b569df4d4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithoutAnnotation.kt @@ -0,0 +1,14 @@ +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +fun withoutAnnotation(x : Int) : Int { + if (x > 0) { + return 1 + withoutAnnotation(x - 1) + } + return 0 +} + +fun box(): String { + val r = withoutAnnotation(10) + if (r == 10) return "OK" + return "Fail $r" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithoutAnnotation.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithoutAnnotation.txt new file mode 100644 index 00000000000..c0078f88d0c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/functionWithoutAnnotation.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public fun withoutAnnotation(/*0*/ x: kotlin.Int): kotlin.Int diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/infixCall.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/infixCall.kt new file mode 100644 index 00000000000..4642b88c175 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/infixCall.kt @@ -0,0 +1,10 @@ +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec infix fun Int.test(x : Int) : Int { + if (this > 1) { + return (this - 1) test x + } + return this +} + +fun box() : String = if (1000000.test(1000000) == 1) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/infixCall.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/infixCall.txt new file mode 100644 index 00000000000..013cb7ee7b5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/infixCall.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public infix tailrec fun kotlin.Int.test(/*0*/ x: kotlin.Int): kotlin.Int diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/infixRecursiveCall.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/infixRecursiveCall.kt new file mode 100644 index 00000000000..09212b1ad4b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/infixRecursiveCall.kt @@ -0,0 +1,14 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec infix fun Int.foo(x: Int) { + if (x == 0) return + val xx = x - 1 + return 1 foo xx +} + +fun box(): String { + 1 foo 1000000 + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/infixRecursiveCall.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/infixRecursiveCall.txt new file mode 100644 index 00000000000..641a4681712 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/infixRecursiveCall.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public infix tailrec fun kotlin.Int.foo(/*0*/ x: kotlin.Int): kotlin.Unit diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/insideElvis.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/insideElvis.kt new file mode 100644 index 00000000000..d758897bde5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/insideElvis.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun test(counter : Int) : Int? { + if (counter < 0) return null + if (counter == 0) return 777 + + return test(-1) ?: test(-2) ?: test(counter - 1) +} + +fun box() : String = + if (test(100000) == 777) "OK" + else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/insideElvis.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/insideElvis.txt new file mode 100644 index 00000000000..4322f6cd06e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/insideElvis.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun test(/*0*/ counter: kotlin.Int): kotlin.Int? diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/labeledThisReferences.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/labeledThisReferences.kt new file mode 100644 index 00000000000..307a0163bca --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/labeledThisReferences.kt @@ -0,0 +1,30 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +class B { + inner class C { + tailrec fun h(counter : Int) { + if (counter > 0) { + this@C.h(counter - 1) + } + } + + tailrec fun h2(x : Any) { + this@B.h2("no recursion") // keep vigilance + } + + } + + fun makeC() : C = C() + + fun h2(x : Any) { + } +} + +fun box() : String { + B().makeC().h(1000000) + B().makeC().h2(0) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/labeledThisReferences.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/labeledThisReferences.txt new file mode 100644 index 00000000000..26d9a88dbad --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/labeledThisReferences.txt @@ -0,0 +1,21 @@ +package + +public fun box(): kotlin.String + +public final class B { + public constructor B() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun h2(/*0*/ x: kotlin.Any): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun makeC(): B.C + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public final inner class C { + public constructor C() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final tailrec fun h(/*0*/ counter: kotlin.Int): kotlin.Unit + public final tailrec fun h2(/*0*/ x: kotlin.Any): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/loops.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/loops.kt new file mode 100644 index 00000000000..0eac7241a86 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/loops.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun test(x : Int) : Int { + var z = if (x > 3) 3 else x + while (z > 0) { + if (z > 10) { + return test(x - 1) + } + test(0) + z = z - 1 + } + + return 1 +} + +fun box() : String = if (test(100000) == 1) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/loops.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/loops.txt new file mode 100644 index 00000000000..865b86f16eb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/loops.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun test(/*0*/ x: kotlin.Int): kotlin.Int diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/multilevelBlocks.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/multilevelBlocks.kt new file mode 100644 index 00000000000..597ca8dd231 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/multilevelBlocks.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun test(x : Int) : Int { + if (x == 1) { + if (x != 1) { + test(0) + return test(0) + } else { + return test(x + test(0)) + } + } else if (x > 0) { + return test(x - 1) + } + return -1 +} + +fun box() : String = if (test(1000000) == -1) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/multilevelBlocks.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/multilevelBlocks.txt new file mode 100644 index 00000000000..865b86f16eb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/multilevelBlocks.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun test(/*0*/ x: kotlin.Int): kotlin.Int diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realIteratorFoldl.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realIteratorFoldl.kt new file mode 100644 index 00000000000..a4523b4320d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realIteratorFoldl.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun Iterator.foldl(acc : A, foldFunction : (e : T, acc : A) -> A) : A = + if (!hasNext()) acc + else foldl(foldFunction(next(), acc), foldFunction) + +fun box() : String { + val sum = (1..1000000).iterator().foldl(0) { e : Int, acc : Long -> + acc + e + } + + return if (sum == 500000500000) "OK" else "FAIL: $sum" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realIteratorFoldl.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realIteratorFoldl.txt new file mode 100644 index 00000000000..5fac038d69c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realIteratorFoldl.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun kotlin.collections.Iterator.foldl(/*0*/ acc: A, /*1*/ foldFunction: (e: T, acc: A) -> A): A diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realStringEscape.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realStringEscape.kt new file mode 100644 index 00000000000..f78c458a8e6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realStringEscape.kt @@ -0,0 +1,17 @@ +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +fun escapeChar(c : Char) : String? = when (c) { + '\\' -> "\\\\" + '\n' -> "\\n" + '"' -> "\\\"" + else -> "" + c +} + +tailrec fun String.escape(i : Int = 0, result : StringBuilder = StringBuilder()) : String = + if (i == length) result.toString() + else escape(i + 1, result.append(escapeChar(get(i)))) + +fun box() : String { + "test me not \\".escape() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realStringEscape.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realStringEscape.txt new file mode 100644 index 00000000000..328683f8d54 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realStringEscape.txt @@ -0,0 +1,5 @@ +package + +public fun box(): kotlin.String +public fun escapeChar(/*0*/ c: kotlin.Char): kotlin.String? +public tailrec fun kotlin.String.escape(/*0*/ i: kotlin.Int = ..., /*1*/ result: kotlin.text.StringBuilder /* = java.lang.StringBuilder */ = ...): kotlin.String diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realStringRepeat.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realStringRepeat.kt new file mode 100644 index 00000000000..2772ef3c3a2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realStringRepeat.kt @@ -0,0 +1,10 @@ +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun String.repeat(num : Int, acc : StringBuilder = StringBuilder()) : String = + if (num == 0) acc.toString() + else repeat(num - 1, acc.append(this)) + +fun box() : String { + val s = "a".repeat(10000) + return if (s.length == 10000) "OK" else "FAIL: ${s.length}" +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realStringRepeat.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realStringRepeat.txt new file mode 100644 index 00000000000..a0d6f90a0f3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/realStringRepeat.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun kotlin.String.repeat(/*0*/ num: kotlin.Int, /*1*/ acc: kotlin.text.StringBuilder /* = java.lang.StringBuilder */ = ...): kotlin.String diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveCallInLambda.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveCallInLambda.kt new file mode 100644 index 00000000000..e53fc49a214 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveCallInLambda.kt @@ -0,0 +1,17 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun foo() { + bar { + foo() + } +} + +fun bar(a: Any) {} + +fun box(): String { + foo() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveCallInLambda.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveCallInLambda.txt new file mode 100644 index 00000000000..8c24a2ff136 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveCallInLambda.txt @@ -0,0 +1,5 @@ +package + +public fun bar(/*0*/ a: kotlin.Any): kotlin.Unit +public fun box(): kotlin.String +public tailrec fun foo(): kotlin.Unit diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveCallInLocalFunction.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveCallInLocalFunction.kt new file mode 100644 index 00000000000..c6e5fe2a79f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveCallInLocalFunction.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun foo() { + fun bar() { + foo() + } +} + +fun box(): String { + foo() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveCallInLocalFunction.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveCallInLocalFunction.txt new file mode 100644 index 00000000000..091eb5de165 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveCallInLocalFunction.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun foo(): kotlin.Unit diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveInnerFunction.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveInnerFunction.kt new file mode 100644 index 00000000000..cf6ac28a2b1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveInnerFunction.kt @@ -0,0 +1,13 @@ +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +fun test() { + tailrec fun g3(counter : Int) { + if (counter > 0) { g3(counter - 1) } + } + g3(1000000) +} + +fun box() : String { + test() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveInnerFunction.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveInnerFunction.txt new file mode 100644 index 00000000000..4b035952c5d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/recursiveInnerFunction.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public fun test(): kotlin.Unit diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnIf.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnIf.kt new file mode 100644 index 00000000000..f974aac542d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnIf.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun test(x : Int) : Int { + return if (x == 1) { + test(x - 1) + 1 + test(x - 1) + } else if (x > 0) { + test(x - 1) + } else { + 0 + } +} + +fun box() : String = if (test(1000000) == 1) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnIf.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnIf.txt new file mode 100644 index 00000000000..865b86f16eb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnIf.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun test(/*0*/ x: kotlin.Int): kotlin.Int diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInCatch.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInCatch.kt new file mode 100644 index 00000000000..94541e9b0ad --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInCatch.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun test(counter : Int) : Int { + if (counter == 0) return 0 + + try { + throw Exception() + } catch (e : Exception) { + return test(counter - 1) + } +} + +fun box() : String = if (test(3) == 0) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInCatch.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInCatch.txt new file mode 100644 index 00000000000..fe405335127 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInCatch.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun test(/*0*/ counter: kotlin.Int): kotlin.Int diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInFinally.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInFinally.kt new file mode 100644 index 00000000000..37c8bde1bd5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInFinally.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun test(counter : Int) : Int { + if (counter == 0) return 0 + + try { + // do nothing + } finally { + return test(counter - 1) + } +} + +fun box() : String = if (test(3) == 0) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInFinally.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInFinally.txt new file mode 100644 index 00000000000..fe405335127 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInFinally.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun test(/*0*/ counter: kotlin.Int): kotlin.Int diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInIfInFinally.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInIfInFinally.kt new file mode 100644 index 00000000000..a91a01c4007 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInIfInFinally.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun test(counter : Int) : Int { + if (counter == 0) return 0 + + try { + // do nothing + } finally { + if (counter > 0) { + return test(counter - 1) + } + } + + return -1 +} + +fun box() : String = if (test(3) == 0) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInIfInFinally.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInIfInFinally.txt new file mode 100644 index 00000000000..fe405335127 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInIfInFinally.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun test(/*0*/ counter: kotlin.Int): kotlin.Int diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInParentheses.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInParentheses.kt new file mode 100644 index 00000000000..6a05a80c18d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInParentheses.kt @@ -0,0 +1,11 @@ +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun foo(x: Int) { + if (x == 0) return + (return foo(x - 1)) +} + +fun box(): String { + foo(1000000) + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInParentheses.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInParentheses.txt new file mode 100644 index 00000000000..4fd18812fe0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInParentheses.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInTry.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInTry.kt new file mode 100644 index 00000000000..f3c225f251e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInTry.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun test(counter : Int) : Int { + if (counter == 0) return 0 + + try { + return test(counter - 1) + } catch (any : Throwable) { + return -1 + } +} + +fun box() : String = if (test(3) == 0) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInTry.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInTry.txt new file mode 100644 index 00000000000..fe405335127 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/returnInTry.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun test(/*0*/ counter: kotlin.Int): kotlin.Int diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleBlock.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleBlock.kt new file mode 100644 index 00000000000..7d2cf67bd63 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleBlock.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun test(x : Int) : Int = + if (x == 1) { + test(x - 1) + 1 + test(x - 1) + } else if (x > 0) { + test(x - 1) + } else { + 0 + } + +fun box() : String = if (test(1000000) == 1) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleBlock.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleBlock.txt new file mode 100644 index 00000000000..865b86f16eb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleBlock.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun test(/*0*/ x: kotlin.Int): kotlin.Int diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleReturn.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleReturn.kt new file mode 100644 index 00000000000..497f0456cf8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleReturn.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun test(x : Int) : Int { + if (x == 10) { + return 1 + test(x - 1) + } + if (x > 0) { + return test(x - 1) + } + return 0 +} + +fun box() : String = if (test(1000000) == 1) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleReturn.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleReturn.txt new file mode 100644 index 00000000000..865b86f16eb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleReturn.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun test(/*0*/ x: kotlin.Int): kotlin.Int diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleReturnWithElse.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleReturnWithElse.kt new file mode 100644 index 00000000000..5e41e54a3cb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleReturnWithElse.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun test(x : Int) : Int { + if (x == 0) { + return 0 + } else if (x == 10) { + test(0) + return 1 + test(x - 1) + } else { + return test(x - 1) + } +} + +fun box() : String = if (test(1000000) == 1) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleReturnWithElse.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleReturnWithElse.txt new file mode 100644 index 00000000000..865b86f16eb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/simpleReturnWithElse.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun test(/*0*/ x: kotlin.Int): kotlin.Int diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/sum.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/sum.kt new file mode 100644 index 00000000000..461f09c5ec1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/sum.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun sum(x: Long, sum: Long): Long { + if (x == 0.toLong()) return sum + return sum(x - 1, sum + x) +} + +fun box() : String { + val sum = sum(1000000, 0) + if (sum != 500000500000.toLong()) return "Fail $sum" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/sum.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/sum.txt new file mode 100644 index 00000000000..cc7cff75ba0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/sum.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun sum(/*0*/ x: kotlin.Long, /*1*/ sum: kotlin.Long): kotlin.Long diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailCallInBlockInParentheses.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailCallInBlockInParentheses.kt new file mode 100644 index 00000000000..92fd0bf3ffb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailCallInBlockInParentheses.kt @@ -0,0 +1,13 @@ +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun foo(x: Int) { + return if (x > 0) { + (foo(x - 1)) + } + else Unit +} + +fun box(): String { + foo(1000000) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailCallInBlockInParentheses.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailCallInBlockInParentheses.txt new file mode 100644 index 00000000000..4fd18812fe0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailCallInBlockInParentheses.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailCallInParentheses.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailCallInParentheses.kt new file mode 100644 index 00000000000..d0c54318be0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailCallInParentheses.kt @@ -0,0 +1,11 @@ +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun foo(x: Int) { + if (x == 0) return + return (foo(x - 1)) +} + +fun box(): String { + foo(1000000) + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailCallInParentheses.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailCallInParentheses.txt new file mode 100644 index 00000000000..4fd18812fe0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailCallInParentheses.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailRecursionInFinally.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailRecursionInFinally.kt new file mode 100644 index 00000000000..a69c34bd44c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailRecursionInFinally.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun test(go: Boolean) : Unit { + if (!go) return + try { + test(false) + } catch (any : Exception) { + test(false) + } finally { + test(false) + } +} + +fun box(): String { + test(true) + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailRecursionInFinally.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailRecursionInFinally.txt new file mode 100644 index 00000000000..883abc7200c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/tailRecursionInFinally.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun test(/*0*/ go: kotlin.Boolean): kotlin.Unit diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/thisReferences.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/thisReferences.kt new file mode 100644 index 00000000000..b067a3c5717 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/thisReferences.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +class A { + tailrec fun f1(c : Int) { + if (c > 0) { + this.f1(c - 1) + } + } + + tailrec fun f2(c : Int) { + if (c > 0) { + f2(c - 1) + } + } + + tailrec fun f3(a : A) { + a.f3(a) // non-tail recursion, could be potentially resolved by condition if (a == this) f3() else a.f3() + } +} + +fun box() : String { + A().f1(1000000) + A().f2(1000000) + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/thisReferences.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/thisReferences.txt new file mode 100644 index 00000000000..c919fcdf798 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/thisReferences.txt @@ -0,0 +1,13 @@ +package + +public fun box(): kotlin.String + +public final class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final tailrec fun f1(/*0*/ c: kotlin.Int): kotlin.Unit + public final tailrec fun f2(/*0*/ c: kotlin.Int): kotlin.Unit + public final tailrec fun f3(/*0*/ a: A): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/unitBlocks.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/unitBlocks.kt new file mode 100644 index 00000000000..9324f76ad43 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/unitBlocks.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun test(x : Int) : Unit { + if (x == 1) { + test(x - 1) + } else if (x == 2) { + test(x - 1) + return + } else if (x == 3) { + test(x - 1) + if (x == 3) { + test(x - 1) + } + return + } else if (x > 0) { + test(x - 1) + } +} + +fun box() : String { + test(1000000) + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/unitBlocks.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/unitBlocks.txt new file mode 100644 index 00000000000..6dd7b2f167f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/unitBlocks.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun test(/*0*/ x: kotlin.Int): kotlin.Unit diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithCondition.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithCondition.kt new file mode 100644 index 00000000000..c87fb69a91e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithCondition.kt @@ -0,0 +1,11 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun withWhen(counter : Int) : Int = + when (counter) { + 0 -> counter + 50 -> 1 + withWhen(counter - 1) + else -> withWhen(counter - 1) + } + +fun box() : String = if (withWhen(100000) == 1) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithCondition.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithCondition.txt new file mode 100644 index 00000000000..1aa338bd9c6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithCondition.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun withWhen(/*0*/ counter: kotlin.Int): kotlin.Int diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithInRange.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithInRange.kt new file mode 100644 index 00000000000..9ceaf639f08 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithInRange.kt @@ -0,0 +1,16 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun withWhen(counter : Int, d : Any) : Int = + when (counter) { + 0 -> counter + 1, 2 -> withWhen(counter - 1, "1,2") + in 3..49 -> withWhen(counter - 1, "3..49") + 50 -> 1 + withWhen(counter - 1, "50") + !in 0..50 -> withWhen(counter - 1, "!0..50") + else -> withWhen(counter - 1, "else") + } + +fun box() : String = if (withWhen(100000, "test") == 1) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithInRange.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithInRange.txt new file mode 100644 index 00000000000..aa55835bd00 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithInRange.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun withWhen(/*0*/ counter: kotlin.Int, /*1*/ d: kotlin.Any): kotlin.Int diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithIs.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithIs.kt new file mode 100644 index 00000000000..d86ee798725 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithIs.kt @@ -0,0 +1,17 @@ +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun withWhen(counter : Int, d : Any) : Int = + if (counter == 0) { + 0 + } + else if (counter == 5) { + withWhen(counter - 1, 999) + } + else + when (d) { + is String -> withWhen(counter - 1, "is String") + is Number -> withWhen(counter, "is Number") + else -> throw IllegalStateException() + } + +fun box() : String = if (withWhen(100000, "test") == 0) "OK" else "FAIL" diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithIs.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithIs.txt new file mode 100644 index 00000000000..aa55835bd00 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithIs.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun withWhen(/*0*/ counter: kotlin.Int, /*1*/ d: kotlin.Any): kotlin.Int diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithoutCondition.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithoutCondition.kt new file mode 100644 index 00000000000..154371bacee --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithoutCondition.kt @@ -0,0 +1,12 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND_WITHOUT_CHECK: JS + +tailrec fun withWhen2(counter : Int) : Int = + when { + counter == 0 -> counter + counter == 50 -> 1 + withWhen2(counter - 1) + withWhen2(0) == 0 -> withWhen2(counter - 1) + else -> 1 + } + +fun box() : String = if (withWhen2(100000) == 1) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithoutCondition.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithoutCondition.txt new file mode 100644 index 00000000000..5426fa21dfd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/functions/tailRecursion/whenWithoutCondition.txt @@ -0,0 +1,4 @@ +package + +public fun box(): kotlin.String +public tailrec fun withWhen2(/*0*/ counter: kotlin.Int): kotlin.Int diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/vararg/kt4172.kt b/backend.native/tests/external/codegen/blackbox/diagnostics/vararg/kt4172.kt new file mode 100644 index 00000000000..80e1489d641 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/vararg/kt4172.kt @@ -0,0 +1,15 @@ +fun box(): String { + main(array()) + return "OK" +} + +fun main(args: Array) { + D.foo(array()) +} + +object D { + fun foo(array: Array) = array +} + +@Suppress("UNCHECKED_CAST") +inline fun array(vararg t : T) : Array = t as Array \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/diagnostics/vararg/kt4172.txt b/backend.native/tests/external/codegen/blackbox/diagnostics/vararg/kt4172.txt new file mode 100644 index 00000000000..2b01eebc3f1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/diagnostics/vararg/kt4172.txt @@ -0,0 +1,13 @@ +package + +@kotlin.Suppress(names = {"UNCHECKED_CAST"}) public inline fun array(/*0*/ vararg t: T /*kotlin.Array*/): kotlin.Array +public fun box(): kotlin.String +public fun main(/*0*/ args: kotlin.Array): kotlin.Unit + +public object D { + private constructor D() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo(/*0*/ array: kotlin.Array): kotlin.Array + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/backend.native/tests/external/codegen/blackbox/elvis/genericNull.kt b/backend.native/tests/external/codegen/blackbox/elvis/genericNull.kt new file mode 100644 index 00000000000..beb1cb723f2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/elvis/genericNull.kt @@ -0,0 +1,8 @@ +fun foo(t: T) { + (t ?: 42).toInt() +} + +fun box(): String { + foo(null) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/elvis/kt6694ExactAnnotationForElvis.kt b/backend.native/tests/external/codegen/blackbox/elvis/kt6694ExactAnnotationForElvis.kt new file mode 100644 index 00000000000..af26c6e87f2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/elvis/kt6694ExactAnnotationForElvis.kt @@ -0,0 +1,19 @@ +interface PsiElement { + fun findChildByType(i: Int): T? = + if (i == 42) JetOperationReferenceExpression() as T else throw Exception() +} +interface JetSimpleNameExpression : PsiElement { + fun getReferencedNameElement(): PsiElement +} +class JetOperationReferenceExpression : JetSimpleNameExpression { + override fun getReferencedNameElement() = this +} +class JetLabelReferenceExpression : JetSimpleNameExpression { + public override fun getReferencedNameElement(): PsiElement = + findChildByType(42) ?: this +} + +fun box(): String { + val element = JetLabelReferenceExpression().getReferencedNameElement() + return if (element is JetOperationReferenceExpression) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/elvis/nullNullOk.kt b/backend.native/tests/external/codegen/blackbox/elvis/nullNullOk.kt new file mode 100644 index 00000000000..e25fe160183 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/elvis/nullNullOk.kt @@ -0,0 +1 @@ +fun box() = null ?: null ?: "OK" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/elvis/primitive.kt b/backend.native/tests/external/codegen/blackbox/elvis/primitive.kt new file mode 100644 index 00000000000..bd3edd1a725 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/elvis/primitive.kt @@ -0,0 +1,6 @@ +fun box(): String { + if ((42 ?: 239) != 42) return "Fail Int" + if ((42.toLong() ?: 239.toLong()) != 42.toLong()) return "Fail Long" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/enum/abstractMethodInEnum.kt b/backend.native/tests/external/codegen/blackbox/enum/abstractMethodInEnum.kt new file mode 100644 index 00000000000..0d3ed6de674 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/abstractMethodInEnum.kt @@ -0,0 +1,9 @@ +enum class A() { + ENTRY(){ override fun t() = "OK"}; + + abstract fun t(): String +} + +fun f(a: A) = a.t() + +fun box()= f(A.ENTRY) diff --git a/backend.native/tests/external/codegen/blackbox/enum/abstractNestedClass.kt b/backend.native/tests/external/codegen/blackbox/enum/abstractNestedClass.kt new file mode 100644 index 00000000000..3994bd54e17 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/abstractNestedClass.kt @@ -0,0 +1,10 @@ +enum class E { + ENTRY; + + abstract class Nested +} + +fun box(): String { + E.ENTRY + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/enum/asReturnExpression.kt b/backend.native/tests/external/codegen/blackbox/enum/asReturnExpression.kt new file mode 100644 index 00000000000..c001e02763a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/asReturnExpression.kt @@ -0,0 +1,14 @@ +// http://youtrack.jetbrains.com/issue/KT-2167 + +enum class Season { + WINTER, + SPRING, + SUMMER, + AUTUMN +} + +fun foo() = Season.SPRING + +fun box() = + if (foo() == Season.SPRING) "OK" + else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/enum/classForEnumEntry.kt b/backend.native/tests/external/codegen/blackbox/enum/classForEnumEntry.kt new file mode 100644 index 00000000000..b82f41487f8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/classForEnumEntry.kt @@ -0,0 +1,35 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +enum class IssueState { + DEFAULT, + FIXED { + override fun ToString() = "K" + }; + + open fun ToString(): String = "O" +} + +fun box(): String { + val field = IssueState::class.java.getField("FIXED") + + val typeName = field.type.name + if (typeName != "IssueState") return "Fail type name: $typeName" + + val className = field.get(null).javaClass.name + if (className != "IssueState\$FIXED") return "Fail class name: $className" + + val classLoader = IssueState::class.java.classLoader + classLoader.loadClass("IssueState\$FIXED") + try { + classLoader.loadClass("IssueState\$DEFAULT") + return "Fail: no class should have been generated for DEFAULT" + } + catch (e: Exception) { + // ok + } + + return IssueState.DEFAULT.ToString() + IssueState.FIXED.ToString() +} diff --git a/backend.native/tests/external/codegen/blackbox/enum/companionObjectInEnum.kt b/backend.native/tests/external/codegen/blackbox/enum/companionObjectInEnum.kt new file mode 100644 index 00000000000..3e6d423f64e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/companionObjectInEnum.kt @@ -0,0 +1,22 @@ +enum class Game { + ROCK, + PAPER, + SCISSORS; + + companion object { + fun foo() = ROCK + val bar = PAPER + val values2 = values() + val scissors = valueOf("SCISSORS") + } +} + +fun box(): String { + if (Game.foo() != Game.ROCK) return "Fail 1" + if (Game.bar != Game.PAPER) return "Fail 2: ${Game.bar}" + if (Game.values().size != 3) return "Fail 3" + if (Game.valueOf("SCISSORS") != Game.SCISSORS) return "Fail 4" + if (Game.values2.size != 3) return "Fail 5" + if (Game.scissors != Game.SCISSORS) return "Fail 6" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/enum/emptyConstructor.kt b/backend.native/tests/external/codegen/blackbox/enum/emptyConstructor.kt new file mode 100644 index 00000000000..df1c476bfb0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/emptyConstructor.kt @@ -0,0 +1,11 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +package test + +enum class My(val s: String) { + ENTRY; + constructor(): this("OK") +} + +fun box() = My.ENTRY.s diff --git a/backend.native/tests/external/codegen/blackbox/enum/emptyEnumValuesValueOf.kt b/backend.native/tests/external/codegen/blackbox/enum/emptyEnumValuesValueOf.kt new file mode 100644 index 00000000000..6cad0c98a04 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/emptyEnumValuesValueOf.kt @@ -0,0 +1,13 @@ +enum class Empty + +fun box(): String { + if (Empty.values().size != 0) return "Fail: ${Empty.values()}" + + try { + val found = Empty.valueOf("nonExistentEntry") + return "Fail: $found" + } + catch (e: Exception) { + return "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/enum/enumInheritedFromTrait.kt b/backend.native/tests/external/codegen/blackbox/enum/enumInheritedFromTrait.kt new file mode 100644 index 00000000000..8171865caed --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/enumInheritedFromTrait.kt @@ -0,0 +1,16 @@ +package test + +fun box() = MyEnum.E1.f() + MyEnum.E2.f() + +enum class MyEnum : T { + E1 { + override fun f() = "O" + }, + E2 { + override fun f() = "K" + } +} + +interface T { + fun f(): String +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/enum/enumShort.kt b/backend.native/tests/external/codegen/blackbox/enum/enumShort.kt new file mode 100644 index 00000000000..78935006d2b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/enumShort.kt @@ -0,0 +1,11 @@ +enum class Color(val rgb: Int) { + RED(0xff0000), + GREEN(0x00ff00), + BLUE(0x0000ff); +} + +fun foo(): Int { + return Color.RED.rgb + Color.GREEN.rgb + Color.BLUE.rgb +} + +fun box() = if (foo() == 0xffffff) "OK" else "Fail: ${foo()}" diff --git a/backend.native/tests/external/codegen/blackbox/enum/enumWithLambdaParameter.kt b/backend.native/tests/external/codegen/blackbox/enum/enumWithLambdaParameter.kt new file mode 100644 index 00000000000..d41886a5370 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/enumWithLambdaParameter.kt @@ -0,0 +1,19 @@ +// KT-4423 Enum with function not compiled + +enum class Sign(val str: String, val func: (x: Int, y: Int) -> Int){ + plus("+", { x, y -> x + y }), + + mult("*", { x, y -> x * y }) { + override fun toString() = "${func(4,5)}" + } +} + +fun box(): String { + val sum = Sign.plus.func(2, 3) + if (sum != 5) return "Fail 1: $sum" + + val product = Sign.mult.toString() + if (product != "20") return "Fail 2: $product" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/enum/inPackage.kt b/backend.native/tests/external/codegen/blackbox/enum/inPackage.kt new file mode 100644 index 00000000000..388eb0a0dd3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/inPackage.kt @@ -0,0 +1,14 @@ +package test + +enum class Season { + WINTER, + SPRING, + SUMMER, + AUTUMN +} + +fun foo(): Season = Season.SPRING + +fun box() = + if (foo() == Season.SPRING) "OK" + else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/enum/inclassobj.kt b/backend.native/tests/external/codegen/blackbox/enum/inclassobj.kt new file mode 100644 index 00000000000..5006013d4b7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/inclassobj.kt @@ -0,0 +1,15 @@ +fun box() = if(Context.operatingSystemType == Context.Companion.OsType.OTHER) "OK" else "fail" + +public class Context +{ + companion object + { + public enum class OsType { + LINUX, + OTHER; + } + + public val operatingSystemType: OsType + get() = OsType.OTHER + } +} diff --git a/backend.native/tests/external/codegen/blackbox/enum/inner.kt b/backend.native/tests/external/codegen/blackbox/enum/inner.kt new file mode 100644 index 00000000000..01ef380fbc3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/inner.kt @@ -0,0 +1,7 @@ +class A { + enum class E { + OK + } +} + +fun box() = A.E.OK.toString() diff --git a/backend.native/tests/external/codegen/blackbox/enum/innerWithExistingClassObject.kt b/backend.native/tests/external/codegen/blackbox/enum/innerWithExistingClassObject.kt new file mode 100644 index 00000000000..139345cc14a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/innerWithExistingClassObject.kt @@ -0,0 +1,8 @@ +class A { + companion object {} + enum class E { + OK + } +} + +fun box() = A.E.OK.toString() diff --git a/backend.native/tests/external/codegen/blackbox/enum/kt1119.kt b/backend.native/tests/external/codegen/blackbox/enum/kt1119.kt new file mode 100644 index 00000000000..6445197faee --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/kt1119.kt @@ -0,0 +1,12 @@ +enum class Direction() { + NORTH { + val someSpecialValue = "OK" + + override fun f() = someSpecialValue + }; + + + abstract fun f():String +} + +fun box() = Direction.NORTH.f() diff --git a/backend.native/tests/external/codegen/blackbox/enum/kt2350.kt b/backend.native/tests/external/codegen/blackbox/enum/kt2350.kt new file mode 100644 index 00000000000..d4a363062b3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/kt2350.kt @@ -0,0 +1,7 @@ +enum class A(val b: String) { + E1("OK"){ override fun t() = b }; + + abstract fun t(): String +} + +fun box()= A.E1.t() diff --git a/backend.native/tests/external/codegen/blackbox/enum/kt9711.kt b/backend.native/tests/external/codegen/blackbox/enum/kt9711.kt new file mode 100644 index 00000000000..096316ed24b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/kt9711.kt @@ -0,0 +1,13 @@ +enum class X { + + B { + val value2 = "OK" + override val value = { value2 } + }; + + abstract val value: () -> String +} + +fun box(): String { + return X.B.value() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/enum/kt9711_2.kt b/backend.native/tests/external/codegen/blackbox/enum/kt9711_2.kt new file mode 100644 index 00000000000..c16ffd7ae3c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/kt9711_2.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +enum class IssueState { + + FIXED { + override fun ToString() = D().k + + fun s() = "OK" + + class D { + val k = s() + } + }; + + open fun ToString() : String = "fail" +} + +fun box(): String { + return IssueState.FIXED.ToString() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/enum/modifierFlags.kt b/backend.native/tests/external/codegen/blackbox/enum/modifierFlags.kt new file mode 100644 index 00000000000..180aaf96346 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/modifierFlags.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +import java.lang.reflect.Modifier + +enum class En { + Y +} + +fun box(): String { + val klass = En::class.java + val superclass = klass.superclass.name + if (superclass != "java.lang.Enum") "Fail superclass: $superclass" + + val enumModifiers = klass.modifiers + if ((enumModifiers and 0x4000) == 0) return "Fail ACC_ENUM on class" + if ((enumModifiers and Modifier.FINAL) == 0) return "Fail FINAL on class" + + val entry = klass.getField("Y") + val entryModifiers = entry.modifiers + if ((entryModifiers and 0x4000) == 0) return "Fail ACC_ENUM on entry" + if ((entryModifiers and Modifier.FINAL) == 0) return "Fail FINAL on entry" + if ((entryModifiers and Modifier.STATIC) == 0) return "Fail FINAL on entry" + if ((entryModifiers and Modifier.PUBLIC) == 0) return "Fail FINAL on entry" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/enum/noClassForSimpleEnum.kt b/backend.native/tests/external/codegen/blackbox/enum/noClassForSimpleEnum.kt new file mode 100644 index 00000000000..03384f24b5b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/noClassForSimpleEnum.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +enum class State { + O, + K +} + +fun box(): String { + val field = State::class.java.getField("O") + val className = field.get(null).javaClass.name + if (className != "State") return "Fail: $className" + + return "${State.O.name}${State.K.name}" +} diff --git a/backend.native/tests/external/codegen/blackbox/enum/objectInEnum.kt b/backend.native/tests/external/codegen/blackbox/enum/objectInEnum.kt new file mode 100644 index 00000000000..9f19d3c1704 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/objectInEnum.kt @@ -0,0 +1,20 @@ +enum class E { + ENTRY, + SUBCLASS { + object O { + fun foo() = 2 + } + override fun bar() = O.foo() + }; + + object O { + fun foo() = 1 + } + open fun bar() = O.foo() +} + +fun box(): String { + if (E.ENTRY.bar() != 1) return "Fail 1" + if (E.SUBCLASS.bar() != 2) return "Fail 2" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/enum/ordinal.kt b/backend.native/tests/external/codegen/blackbox/enum/ordinal.kt new file mode 100644 index 00000000000..d66c3e0ae4e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/ordinal.kt @@ -0,0 +1,8 @@ +enum class State { + _0, + _1, + _2, + _3 +} + +fun box() = if(State._0.ordinal == 0 && State._1.ordinal == 1 && State._2.ordinal == 2 && State._3.ordinal == 3) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/enum/simple.kt b/backend.native/tests/external/codegen/blackbox/enum/simple.kt new file mode 100644 index 00000000000..ed48d29a5d9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/simple.kt @@ -0,0 +1,12 @@ +enum class Season { + WINTER, + SPRING, + SUMMER, + AUTUMN +} + +fun foo(): Season = Season.SPRING + +fun box() = + if (foo() == Season.SPRING) "OK" + else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/enum/sortEnumEntries.kt b/backend.native/tests/external/codegen/blackbox/enum/sortEnumEntries.kt new file mode 100644 index 00000000000..8b894a1ffe2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/sortEnumEntries.kt @@ -0,0 +1,18 @@ +// WITH_RUNTIME + +import Game.* + +enum class Game { + ROCK, + PAPER, + SCISSORS, + LIZARD, + SPOCK +} + +fun box(): String { + val a = arrayOf(LIZARD, SCISSORS, SPOCK, ROCK, PAPER) + a.sort() + val str = a.joinToString(" ") + return if (str == "ROCK PAPER SCISSORS LIZARD SPOCK") "OK" else "Fail: $str" +} diff --git a/backend.native/tests/external/codegen/blackbox/enum/superCallInEnumLiteral.kt b/backend.native/tests/external/codegen/blackbox/enum/superCallInEnumLiteral.kt new file mode 100644 index 00000000000..11507d9d147 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/superCallInEnumLiteral.kt @@ -0,0 +1,18 @@ +package test + +fun box() = E.E1.f() + E.E2.f() + +enum class E { + E1 { + override fun f(): String { + return super.f() + "O" + } + }, + E2 { + override fun f(): String { + return super.f() + "K" + } + }; + + open fun f() = "" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/enum/toString.kt b/backend.native/tests/external/codegen/blackbox/enum/toString.kt new file mode 100644 index 00000000000..b4890365b12 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/toString.kt @@ -0,0 +1,6 @@ +enum class State { + O, + K +} + +fun box() = "${State.O}${State.K}" diff --git a/backend.native/tests/external/codegen/blackbox/enum/valueof.kt b/backend.native/tests/external/codegen/blackbox/enum/valueof.kt new file mode 100644 index 00000000000..89aeaa9cce6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/enum/valueof.kt @@ -0,0 +1,22 @@ +enum class Color { + RED, + BLUE +} + +fun throwsOnGreen(): Boolean { + try { + Color.valueOf("GREEN") + return false + } + catch (e: Exception) { + return true + } +} + +fun box() = if( + Color.valueOf("RED") == Color.RED + && Color.valueOf("BLUE") == Color.BLUE + && Color.values()[0] == Color.RED + && Color.values()[1] == Color.BLUE + && throwsOnGreen() + ) "OK" else "fail" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/evaluate/char.kt b/backend.native/tests/external/codegen/blackbox/evaluate/char.kt new file mode 100644 index 00000000000..06d5b9d24d7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/evaluate/char.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +package test + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann(val c1: Int) + +@Ann('a' - 'a') class MyClass + +fun box(): String { + val annotation = MyClass::class.java.getAnnotation(Ann::class.java)!! + if (annotation.c1 != 0) return "fail : expected = ${1}, actual = ${annotation.c1}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/evaluate/divide.kt b/backend.native/tests/external/codegen/blackbox/evaluate/divide.kt new file mode 100644 index 00000000000..38dcc8cb811 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/evaluate/divide.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann( + val b: Byte, + val s: Short, + val i: Int, + val l: Long +) + +@Ann(1 / 1, 1 / 1, 1 / 1, 1 / 1) class MyClass + +fun box(): String { + val annotation = MyClass::class.java.getAnnotation(Ann::class.java)!! + if (annotation.b != 1.toByte()) return "fail 1" + if (annotation.s != 1.toShort()) return "fail 2" + if (annotation.i != 1) return "fail 2" + if (annotation.l != 1.toLong()) return "fail 2" + return "OK" +} + +// EXPECTED: Ann[b = IntegerValueType(1): IntegerValueType(1), i = IntegerValueType(1): IntegerValueType(1), l = IntegerValueType(1): IntegerValueType(1), s = IntegerValueType(1): IntegerValueType(1)] diff --git a/backend.native/tests/external/codegen/blackbox/evaluate/intrinsics.kt b/backend.native/tests/external/codegen/blackbox/evaluate/intrinsics.kt new file mode 100644 index 00000000000..44599301319 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/evaluate/intrinsics.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann( + val p1: Int, + val p2: Short, + val p3: Byte, + val p4: Int, + val p5: Int, + val p6: Int +) + +val prop1: Int = 1 or 1 +val prop2: Short = 1 and 1 +val prop3: Byte = 1 xor 1 +val prop4: Int = 1 shl 1 +val prop5: Int = 1 shr 1 +val prop6: Int = 1 ushr 1 + +@Ann(1 or 1, 1 and 1, 1 xor 1, 1 shl 1, 1 shr 1, 1 ushr 1) class MyClass + +fun box(): String { + val annotation = MyClass::class.java.getAnnotation(Ann::class.java)!! + if (annotation.p1 != prop1) return "fail 1, expected = ${prop1}, actual = ${annotation.p1}" + if (annotation.p2 != prop2) return "fail 2, expected = ${prop2}, actual = ${annotation.p2}" + if (annotation.p3 != prop3) return "fail 3, expected = ${prop3}, actual = ${annotation.p3}" + if (annotation.p4 != prop4) return "fail 4, expected = ${prop4}, actual = ${annotation.p4}" + if (annotation.p5 != prop5) return "fail 5, expected = ${prop5}, actual = ${annotation.p5}" + if (annotation.p6 != prop6) return "fail 6, expected = ${prop6}, actual = ${annotation.p6}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/evaluate/kt9443.kt b/backend.native/tests/external/codegen/blackbox/evaluate/kt9443.kt new file mode 100644 index 00000000000..9a8946a9e79 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/evaluate/kt9443.kt @@ -0,0 +1,20 @@ +// WITH_RUNTIME + +abstract class BaseClass { + protected open val menuId: Int = 0 + + public fun run(): Pair = + "$menuId" to (menuId == 0) +} + +class ImplClass: BaseClass() { + override val menuId: Int = 3 +} + +public fun box(): String { + val result = ImplClass().run() + + if (result != ("3" to false)) return "Fail: $result" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/evaluate/maxValue.kt b/backend.native/tests/external/codegen/blackbox/evaluate/maxValue.kt new file mode 100644 index 00000000000..a1f919bb03f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/evaluate/maxValue.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann( + val p1: Int, + val p2: Int, + val p3: Int, + val p4: Int, + val p5: Long, + val p6: Long +) + +@Ann( + p1 = java.lang.Byte.MAX_VALUE + 1, + p2 = java.lang.Short.MAX_VALUE + 1, + p3 = java.lang.Integer.MAX_VALUE + 1, + p4 = java.lang.Integer.MAX_VALUE + 1, + p5 = java.lang.Integer.MAX_VALUE + 1.toLong(), + p6 = java.lang.Long.MAX_VALUE + 1 +) class MyClass + +fun box(): String { + val annotation = MyClass::class.java.getAnnotation(Ann::class.java)!! + if (annotation.p1 != 128) return "fail 1, expected = ${128}, actual = ${annotation.p1}" + if (annotation.p2 != 32768) return "fail 2, expected = ${32768}, actual = ${annotation.p2}" + if (annotation.p3 != -2147483648) return "fail 3, expected = ${-2147483648}, actual = ${annotation.p3}" + if (annotation.p4 != -2147483648) return "fail 4, expected = ${-2147483648}, actual = ${annotation.p4}" + if (annotation.p5 != 2147483648.toLong()) return "fail 5, expected = ${2147483648}, actual = ${annotation.p5}" + if (annotation.p6 != java.lang.Long.MAX_VALUE + 1) return "fail 5, expected = ${java.lang.Long.MAX_VALUE + 1}, actual = ${annotation.p6}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/evaluate/maxValueByte.kt b/backend.native/tests/external/codegen/blackbox/evaluate/maxValueByte.kt new file mode 100644 index 00000000000..82cd51d0364 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/evaluate/maxValueByte.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann( + val p1: Int, + val p2: Byte, + val p4: Int, + val p5: Int +) + +@Ann( + p1 = java.lang.Byte.MAX_VALUE + 1, + p2 = 1 + 1, + p4 = 1 + 1, + p5 = 1.toByte() + 1 +) class MyClass + +fun box(): String { + val annotation = MyClass::class.java.getAnnotation(Ann::class.java)!! + if (annotation.p1 != 128) return "fail 1, expected = ${128}, actual = ${annotation.p1}" + if (annotation.p2 != 2.toByte()) return "fail 2, expected = ${2}, actual = ${annotation.p2}" + if (annotation.p4 != 2) return "fail 4, expected = ${2}, actual = ${annotation.p4}" + if (annotation.p5 != 2) return "fail 5, expected = ${2}, actual = ${annotation.p5}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/evaluate/maxValueInt.kt b/backend.native/tests/external/codegen/blackbox/evaluate/maxValueInt.kt new file mode 100644 index 00000000000..177fd8cb2c8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/evaluate/maxValueInt.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann( + val p1: Int, + val p2: Int, + val p4: Long, + val p5: Int +) + +@Ann( + p1 = java.lang.Integer.MAX_VALUE + 1, + p2 = 1 + 1, + p4 = 1 + 1, + p5 = 1.toInt() + 1.toInt() +) class MyClass + +fun box(): String { + val annotation = MyClass::class.java.getAnnotation(Ann::class.java)!! + if (annotation.p1 != -2147483648) return "fail 1, expected = ${-2147483648}, actual = ${annotation.p1}" + if (annotation.p2 != 2) return "fail 2, expected = ${2}, actual = ${annotation.p2}" + if (annotation.p4 != 2.toLong()) return "fail 4, expected = ${2}, actual = ${annotation.p4}" + if (annotation.p5 != 2) return "fail 5, expected = ${2}, actual = ${annotation.p5}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/evaluate/minus.kt b/backend.native/tests/external/codegen/blackbox/evaluate/minus.kt new file mode 100644 index 00000000000..d0892dadd08 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/evaluate/minus.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann( + val p1: Byte, + val p2: Short, + val p3: Int, + val p4: Long, + val p5: Double, + val p6: Float +) + +val prop1: Byte = 1 - 1 +val prop2: Short = 1 - 1 +val prop3: Int = 1 - 1 +val prop4: Long = 1 - 1 +val prop5: Double = 1.0 - 1.0 +val prop6: Float = 1.0.toFloat() - 1.0.toFloat() + +@Ann(1 - 1, 1 - 1, 1 - 1, 1 - 1, 1.0 - 1.0, 1.0.toFloat() - 1.0.toFloat()) class MyClass + +fun box(): String { + val annotation = MyClass::class.java.getAnnotation(Ann::class.java)!! + if (annotation.p1 != prop1) return "fail 1, expected = ${prop1}, actual = ${annotation.p1}" + if (annotation.p2 != prop2) return "fail 2, expected = ${prop2}, actual = ${annotation.p2}" + if (annotation.p3 != prop3) return "fail 3, expected = ${prop3}, actual = ${annotation.p3}" + if (annotation.p4 != prop4) return "fail 4, expected = ${prop4}, actual = ${annotation.p4}" + if (annotation.p5 != prop5) return "fail 5, expected = ${prop5}, actual = ${annotation.p5}" + if (annotation.p6 != prop6) return "fail 6, expected = ${prop6}, actual = ${annotation.p6}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/evaluate/mod.kt b/backend.native/tests/external/codegen/blackbox/evaluate/mod.kt new file mode 100644 index 00000000000..dbfe458a3ce --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/evaluate/mod.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann( + val p1: Byte, + val p2: Short, + val p3: Int, + val p4: Long, + val p5: Double, + val p6: Float +) + +val prop1: Byte = 1 % 1 +val prop2: Short = 1 % 1 +val prop3: Int = 1 % 1 +val prop4: Long = 1 % 1 +val prop5: Double = 1.0 % 1.0 +val prop6: Float = 1.0.toFloat() % 1.0.toFloat() + +@Ann(1 % 1, 1 % 1, 1 % 1, 1 % 1, 1.0 % 1.0, 1.0.toFloat() % 1.0.toFloat()) class MyClass + +fun box(): String { + val annotation = MyClass::class.java.getAnnotation(Ann::class.java)!! + if (annotation.p1 != prop1) return "fail 1, expected = ${prop1}, actual = ${annotation.p1}" + if (annotation.p2 != prop2) return "fail 2, expected = ${prop2}, actual = ${annotation.p2}" + if (annotation.p3 != prop3) return "fail 3, expected = ${prop3}, actual = ${annotation.p3}" + if (annotation.p4 != prop4) return "fail 4, expected = ${prop4}, actual = ${annotation.p4}" + if (annotation.p5 != prop5) return "fail 5, expected = ${prop5}, actual = ${annotation.p5}" + if (annotation.p6 != prop6) return "fail 6, expected = ${prop6}, actual = ${annotation.p6}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/evaluate/multiply.kt b/backend.native/tests/external/codegen/blackbox/evaluate/multiply.kt new file mode 100644 index 00000000000..8dfd50cd2d2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/evaluate/multiply.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann( + val p1: Byte, + val p2: Short, + val p3: Int, + val p4: Long, + val p5: Double, + val p6: Float +) + +val prop1: Byte = 1 * 1 +val prop2: Short = 1 * 1 +val prop3: Int = 1 * 1 +val prop4: Long = 1 * 1 +val prop5: Double = 1.0 * 1.0 +val prop6: Float = 1.0.toFloat() * 1.0.toFloat() + +@Ann(1 * 1, 1 * 1, 1 * 1, 1 * 1, 1.0 * 1.0, 1.0.toFloat() * 1.0.toFloat()) class MyClass + +fun box(): String { + val annotation = MyClass::class.java.getAnnotation(Ann::class.java)!! + if (annotation.p1 != prop1) return "fail 1, expected = ${prop1}, actual = ${annotation.p1}" + if (annotation.p2 != prop2) return "fail 2, expected = ${prop2}, actual = ${annotation.p2}" + if (annotation.p3 != prop3) return "fail 3, expected = ${prop3}, actual = ${annotation.p3}" + if (annotation.p4 != prop4) return "fail 4, expected = ${prop4}, actual = ${annotation.p4}" + if (annotation.p5 != prop5) return "fail 5, expected = ${prop5}, actual = ${annotation.p5}" + if (annotation.p6 != prop6) return "fail 6, expected = ${prop6}, actual = ${annotation.p6}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/evaluate/parenthesized.kt b/backend.native/tests/external/codegen/blackbox/evaluate/parenthesized.kt new file mode 100644 index 00000000000..417358d64e0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/evaluate/parenthesized.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann( + val p1: Byte, + val p2: Short, + val p3: Int, + val p4: Long, + val p5: Double, + val p6: Float +) + +val prop1: Byte = (1 + 2) * 2 +val prop2: Short = (1 + 2) * 2 +val prop3: Int = (1 + 2) * 2 +val prop4: Long = (1 + 2) * 2 +val prop5: Double = (1.0 + 2) * 2 +val prop6: Float = (1.toFloat() + 2) * 2 + +@Ann((1 + 2) * 2, (1 + 2) * 2, (1 + 2) * 2, (1 + 2) * 2, (1.0 + 2) * 2, (1.toFloat() + 2) * 2) class MyClass + +fun box(): String { + val annotation = MyClass::class.java.getAnnotation(Ann::class.java)!! + if (annotation.p1 != prop1) return "fail 1, expected = ${prop1}, actual = ${annotation.p1}" + if (annotation.p2 != prop2) return "fail 2, expected = ${prop2}, actual = ${annotation.p2}" + if (annotation.p3 != prop3) return "fail 3, expected = ${prop3}, actual = ${annotation.p3}" + if (annotation.p4 != prop4) return "fail 4, expected = ${prop4}, actual = ${annotation.p4}" + if (annotation.p5 != prop5) return "fail 5, expected = ${prop5}, actual = ${annotation.p5}" + if (annotation.p6 != prop6) return "fail 6, expected = ${prop6}, actual = ${annotation.p6}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/evaluate/plus.kt b/backend.native/tests/external/codegen/blackbox/evaluate/plus.kt new file mode 100644 index 00000000000..622a3728343 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/evaluate/plus.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann( + val p1: Byte, + val p2: Short, + val p3: Int, + val p4: Long, + val p5: Double, + val p6: Float +) + +val prop1: Byte = 1 + 1 +val prop2: Short = 1 + 1 +val prop3: Int = 1 + 1 +val prop4: Long = 1 + 1 +val prop5: Double = 1.0 + 1.0 +val prop6: Float = 1.0.toFloat() + 1.0.toFloat() + +@Ann(1 + 1, 1 + 1, 1 + 1, 1 + 1, 1.0 + 1.0, 1.0.toFloat() + 1.0.toFloat()) class MyClass + +fun box(): String { + val annotation = MyClass::class.java.getAnnotation(Ann::class.java)!! + if (annotation.p1 != prop1) return "fail 1, expected = ${prop1}, actual = ${annotation.p1}" + if (annotation.p2 != prop2) return "fail 2, expected = ${prop2}, actual = ${annotation.p2}" + if (annotation.p3 != prop3) return "fail 3, expected = ${prop3}, actual = ${annotation.p3}" + if (annotation.p4 != prop4) return "fail 4, expected = ${prop4}, actual = ${annotation.p4}" + if (annotation.p5 != prop5) return "fail 5, expected = ${prop5}, actual = ${annotation.p5}" + if (annotation.p6 != prop6) return "fail 6, expected = ${prop6}, actual = ${annotation.p6}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/evaluate/simpleCallBinary.kt b/backend.native/tests/external/codegen/blackbox/evaluate/simpleCallBinary.kt new file mode 100644 index 00000000000..b141e7002cb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/evaluate/simpleCallBinary.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann( + val p1: Int, + val p2: Int, + val p3: Int, + val p4: Int, + val p5: Int +) + +const val prop1: Int = 1.plus(1) +const val prop2: Int = 1.minus(1) +const val prop3: Int = 1.times(1) +const val prop4: Int = 1.div(1) +const val prop5: Int = 1.mod(1) + +@Ann(prop1, prop2, prop3, prop4, prop5) class MyClass + +fun box(): String { + val annotation = MyClass::class.java.getAnnotation(Ann::class.java)!! + if (annotation.p1 != prop1) return "fail 1, expected = ${prop1}, actual = ${annotation.p1}" + if (annotation.p2 != prop2) return "fail 2, expected = ${prop2}, actual = ${annotation.p2}" + if (annotation.p3 != prop3) return "fail 3, expected = ${prop3}, actual = ${annotation.p3}" + if (annotation.p4 != prop4) return "fail 4, expected = ${prop4}, actual = ${annotation.p4}" + if (annotation.p5 != prop5) return "fail 5, expected = ${prop5}, actual = ${annotation.p5}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/evaluate/unaryMinus.kt b/backend.native/tests/external/codegen/blackbox/evaluate/unaryMinus.kt new file mode 100644 index 00000000000..7d3e5bdcaed --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/evaluate/unaryMinus.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann( + val p1: Byte, + val p2: Short, + val p3: Int, + val p4: Long, + val p5: Double, + val p6: Float +) + +const val prop1: Byte = -1 +const val prop2: Short = -1 +const val prop3: Int = -1 +const val prop4: Long = -1 +const val prop5: Double = -1.0 +const val prop6: Float = -1.0.toFloat() + +@Ann(prop1, prop2, prop3, prop4, prop5, prop6) class MyClass + +fun box(): String { + val annotation = MyClass::class.java.getAnnotation(Ann::class.java)!! + if (annotation.p1 != prop1) return "fail 1, expected = ${prop1}, actual = ${annotation.p1}" + if (annotation.p2 != prop2) return "fail 2, expected = ${prop2}, actual = ${annotation.p2}" + if (annotation.p3 != prop3) return "fail 3, expected = ${prop3}, actual = ${annotation.p3}" + if (annotation.p4 != prop4) return "fail 4, expected = ${prop4}, actual = ${annotation.p4}" + if (annotation.p5 != prop5) return "fail 5, expected = ${prop5}, actual = ${annotation.p5}" + if (annotation.p6 != prop6) return "fail 6, expected = ${prop6}, actual = ${annotation.p6}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/evaluate/unaryPlus.kt b/backend.native/tests/external/codegen/blackbox/evaluate/unaryPlus.kt new file mode 100644 index 00000000000..2ab595d7f83 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/evaluate/unaryPlus.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann( + val p1: Byte, + val p2: Short, + val p3: Int, + val p4: Long, + val p5: Double, + val p6: Float +) + +const val prop1: Byte = +1 +const val prop2: Short = +1 +const val prop3: Int = +1 +const val prop4: Long = +1 +const val prop5: Double = +1.0 +const val prop6: Float = +1.0.toFloat() + +@Ann(prop1, prop2, prop3, prop4, prop5, prop6) class MyClass + +fun box(): String { + val annotation = MyClass::class.java.getAnnotation(Ann::class.java)!! + if (annotation.p1 != prop1) return "fail 1, expected = ${prop1}, actual = ${annotation.p1}" + if (annotation.p2 != prop2) return "fail 2, expected = ${prop2}, actual = ${annotation.p2}" + if (annotation.p3 != prop3) return "fail 3, expected = ${prop3}, actual = ${annotation.p3}" + if (annotation.p4 != prop4) return "fail 4, expected = ${prop4}, actual = ${annotation.p4}" + if (annotation.p5 != prop5) return "fail 5, expected = ${prop5}, actual = ${annotation.p5}" + if (annotation.p6 != prop6) return "fail 6, expected = ${prop6}, actual = ${annotation.p6}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/exclExcl/genericNull.kt b/backend.native/tests/external/codegen/blackbox/exclExcl/genericNull.kt new file mode 100644 index 00000000000..0d4f831dfb7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/exclExcl/genericNull.kt @@ -0,0 +1,12 @@ +fun foo(t: T) { + t!! +} + +fun box(): String { + try { + foo(null) + } catch (e: Exception) { + return "OK" + } + return "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/exclExcl/primitive.kt b/backend.native/tests/external/codegen/blackbox/exclExcl/primitive.kt new file mode 100644 index 00000000000..d7815756041 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/exclExcl/primitive.kt @@ -0,0 +1,5 @@ +fun box(): String { + 42!! + 42.toLong()!! + return "OK"!! +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/executionOrder.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/executionOrder.kt new file mode 100644 index 00000000000..38cdf5f0d5b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/executionOrder.kt @@ -0,0 +1,19 @@ +var result = "" + +fun getReceiver() : Int { + result += "getReceiver->" + return 1 +} + +fun getFun(b : Int.(Int)->Unit): Int.(Int)->Unit { + result += "getFun()->" + return b +} + +fun box(): String { + getReceiver().(getFun({ result +="End" }))(1) + + if(result != "getFun()->getReceiver->End") return "fail $result" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1061.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1061.kt new file mode 100644 index 00000000000..051768c9c74 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1061.kt @@ -0,0 +1,7 @@ +//KT-1061 Can't call function defined as a val + +object X { + val doit = { i: Int -> i } +} + +fun box() : String = if (X.doit(3) == 3) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1249.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1249.kt new file mode 100644 index 00000000000..8078f5443fe --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1249.kt @@ -0,0 +1,12 @@ +//KT-1249 IllegalStateException invoking function property +class TestClass(val body : () -> Unit) : Any() { + fun run() { + body() + } +} + +fun box() : String { + TestClass({}).run() + return "OK" +} + diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1290.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1290.kt new file mode 100644 index 00000000000..19f03dc8883 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1290.kt @@ -0,0 +1,14 @@ +//KT-1290 Method property in constructor causes NPE + +class Foo(val filter: (T) -> Boolean) { + public fun bar(tee: T) : Boolean { + return filter(tee); + } +} + +fun foo() = Foo({ i: Int -> i < 5 }).bar(2) + +fun box() : String { + if (!foo()) return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1776.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1776.kt new file mode 100644 index 00000000000..5174d4cc374 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1776.kt @@ -0,0 +1,20 @@ +interface Expr { + public fun ttFun() : Int = 12 +} + +class Num(val value : Int) : Expr + +fun Expr.sometest() : Int { + if (this is Num) { + value + return value + } + return 0; +} + + +fun box() : String { + if (Num(11).sometest() != 11) return "fail ${Num(11).sometest()}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1953.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1953.kt new file mode 100644 index 00000000000..c7f72f666f5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1953.kt @@ -0,0 +1,9 @@ +fun box(): String { + val sb = StringBuilder() + operator fun String.unaryPlus() { + sb.append(this) + } + + +"OK" + return sb.toString()!! +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1953_class.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1953_class.kt new file mode 100644 index 00000000000..e2feab63b56 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt1953_class.kt @@ -0,0 +1,14 @@ +class A { + private val sb: StringBuilder = StringBuilder() + + operator fun String.unaryPlus() { + sb.append(this) + } + + fun foo(): String { + +"OK" + return sb.toString()!! + } +} + +fun box(): String = A().foo() diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt3285.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt3285.kt new file mode 100644 index 00000000000..2874bcdb2e8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt3285.kt @@ -0,0 +1,32 @@ +var sayResult = "" + +class NoiseMaker { + fun say(str: String) { sayResult += str } +} + +fun noiseMaker(f: NoiseMaker.() -> Unit) { + val noiseMaker = NoiseMaker() + noiseMaker.f() +} + +abstract class Pet { + fun NoiseMaker.playWith(friend: T) { + say("Playing with " + friend) + } + + abstract fun play(): Unit +} + +class Doggy(): Pet() { + override fun play() = noiseMaker { + say("Time to play! ") + playWith("my owner!") + } +} + +fun box(): String { + Doggy().play() + if (sayResult != "Time to play! Playing with my owner!") return "fail: $sayResult" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt3298.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt3298.kt new file mode 100644 index 00000000000..d0f83531a69 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt3298.kt @@ -0,0 +1,13 @@ +var result = "" +fun result(r: String) { result = r } + +object Foo { + private operator fun String.unaryPlus() = "(" + this + ")" + + fun foo() = { result(+"Stuff") }() +} + +fun box(): String { + Foo.foo() + return if (result == "(Stuff)") "OK" else "Fail $result" +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt3646.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt3646.kt new file mode 100644 index 00000000000..119436fa248 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt3646.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun test(cl: Int.() -> Int):Int = 11.cl() + +class Foo { + val a = test { this } +} + +fun box(): String { + if (Foo().a != 11) return "fail" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt3969.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt3969.kt new file mode 100644 index 00000000000..1e34286ea50 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt3969.kt @@ -0,0 +1,19 @@ +var result = "Fail" + +class A + +operator fun A.inc(s: String = "OK"): A { + result = s + return this +} + +fun box(): String { + var a = A() + a++ + if (result != "OK") return "Fail 1" + + result = "Fail" + ++a + + return result +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt4228.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt4228.kt new file mode 100644 index 00000000000..9906d20305f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt4228.kt @@ -0,0 +1,14 @@ +class A { + companion object +} + +val foo: Any.() -> Unit = {} + +fun test() { + A.(foo)() +} + +fun box(): String { + test() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt475.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt475.kt new file mode 100644 index 00000000000..f81998986f4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt475.kt @@ -0,0 +1,17 @@ + +fun box() : String { + val array = ArrayList() + array.add("0") + array.add("1") + array.add("2") + array.last = "5" + return if(array.length == 3 && array.last == "5") "OK" else "fail" +} + +var ArrayList.length : Int + get() = size + set(value: Int) = throw Error() + +var ArrayList.last : T + get() = get(size-1)!! + set(el : T) { set(size-1, el) } diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt5467.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt5467.kt new file mode 100644 index 00000000000..5d5ab0473a5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt5467.kt @@ -0,0 +1,20 @@ +fun String.foo() : String { + fun Int.bar() : String { + fun Long.baz() : String { + val x = this@foo + val y = this@bar + val z = this@baz + return "$x $y $z" + } + return 0L.baz() + } + return 42.bar() +} + +fun box() : String { + val result = "OK".foo() + + if (result != "OK 42 0") return "fail: $result" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt606.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt606.kt new file mode 100644 index 00000000000..c2199521e9e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt606.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +package kt606 + +//KT-606 wrong resolved call + +class StandardPipelineFactory(val config : ChannelPipeline.() -> Unit) : ChannelPipelineFactory { + override fun getPipeline() : ChannelPipeline { + val pipeline : ChannelPipeline = DefaultChannelPipeline() + pipeline.config() + return pipeline + } +} + +interface ChannelPipeline { + fun print(any: Any) +} + +class DefaultChannelPipeline : ChannelPipeline { + override fun print(any: Any) { + System.out?.println(any) + } + +} + +interface ChannelPipelineFactory { + fun getPipeline() : ChannelPipeline +} + +fun box() : String { + StandardPipelineFactory({ print("OK") }).getPipeline() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt865.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt865.kt new file mode 100644 index 00000000000..b461ec16a08 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/kt865.kt @@ -0,0 +1,17 @@ +class Template() { + val collected = ArrayList() + + operator fun String.unaryPlus() { + collected.add(this@unaryPlus) + } + + fun test() { + + "239" + } +} + +fun box() : String { + val u = Template() + u.test() + return if(u.collected.size == 1 && u.collected.get(0) == "239") "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/nested2.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/nested2.kt new file mode 100644 index 00000000000..9c0aecd0ffb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/nested2.kt @@ -0,0 +1,8 @@ +fun box() : String { + val y = 12 + val op = { x:Int -> (x + y).toString() } + + val op2 : Int.(Int) -> String = { op(this + it) } + + return if("27" == 5.op2(10)) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/shared.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/shared.kt new file mode 100644 index 00000000000..3cf651590a4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/shared.kt @@ -0,0 +1,13 @@ +infix fun T.mustBe(t : T) { + assert("$this must be $t") {this == t} +} + +inline fun assert(message : String, condition : () -> Boolean) { + if (!condition()) + throw AssertionError(message) +} + +fun box() : String { + "lala" mustBe "lala" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/simple.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/simple.kt new file mode 100644 index 00000000000..101e52661bf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/simple.kt @@ -0,0 +1,5 @@ +fun StringBuilder.first() = this.get(0) + +fun foo() = StringBuilder("foo").first() + +fun box() = if (foo() == 'f') "OK" else "Fail ${foo()}" diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/thisMethodInObjectLiteral.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/thisMethodInObjectLiteral.kt new file mode 100644 index 00000000000..cf541e2edb4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/thisMethodInObjectLiteral.kt @@ -0,0 +1,15 @@ +class Test { + private fun T.self() = object{ + fun calc() : T { + return this@self + } + } + + fun box() : Int { + return 1.self().calc() + 1 + } +} + +fun box() : String { + return if (Test().box() == 2) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/virtual.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/virtual.kt new file mode 100644 index 00000000000..cc8a6a72f1a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/virtual.kt @@ -0,0 +1,24 @@ +class Request(val path: String) { + +} + +class Handler() { + fun Int.times(op: ()-> Unit) { + for(i in 0..this) + op() + } + +// fun Request.getPath() : String { +// val sb = java.lang.StringBuilder() +// 10.times { +// sb.append(path)?.append(this) +// } +// return sb.toString() as String +// } + + fun Request.getPath() = path + + fun test(request: Request) = request.getPath() +} + +fun box() : String = if(Handler().test(Request("239")) == "239") "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/extensionFunctions/whenFail.kt b/backend.native/tests/external/codegen/blackbox/extensionFunctions/whenFail.kt new file mode 100644 index 00000000000..2439ddcc2b9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionFunctions/whenFail.kt @@ -0,0 +1,27 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun StringBuilder.takeFirst(): Char { + if (this.length == 0) return 0.toChar() + val c = this.get(0) + this.deleteCharAt(0) + return c +} + +fun foo(expr: StringBuilder): Int { + val c = expr.takeFirst() + when(c) { + 0.toChar() -> throw Exception("zero") + else -> throw Exception("nonzero" + c) + } +} + +fun box(): String { + try { + foo(StringBuilder()) + return "Fail" + } + catch (e: Exception) { + return "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionProperties/accessorForPrivateSetter.kt b/backend.native/tests/external/codegen/blackbox/extensionProperties/accessorForPrivateSetter.kt new file mode 100644 index 00000000000..6dae405db6d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionProperties/accessorForPrivateSetter.kt @@ -0,0 +1,21 @@ +class A { + var result = "Fail" + + private var Int.foo: String + get() = result + private set(value) { + result = value + } + + fun run(): String { + class O { + fun run() { + 42.foo = "OK" + } + } + O().run() + return (-42).foo + } +} + +fun box() = A().run() diff --git a/backend.native/tests/external/codegen/blackbox/extensionProperties/genericValForPrimitiveType.kt b/backend.native/tests/external/codegen/blackbox/extensionProperties/genericValForPrimitiveType.kt new file mode 100644 index 00000000000..787ea1c0245 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionProperties/genericValForPrimitiveType.kt @@ -0,0 +1,39 @@ +val T.valProp: T + get() = this + +class A { + val int: Int = 0 + val long: Long = 0.toLong() + val short: Short = 0.toShort() + val byte: Byte = 0.toByte() + val double: Double = 0.0 + val float: Float = 0.0f + val char: Char = '0' + val bool: Boolean = false + + operator fun invoke() { + int.valProp + long.valProp + short.valProp + byte.valProp + double.valProp + float.valProp + char.valProp + bool.valProp + } +} + +fun box(): String { + 0.valProp + false.valProp + '0'.valProp + 0.0.valProp + 0.0f.valProp + 0.toByte().valProp + 0.toShort().valProp + 0.toLong().valProp + + A()() + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/extensionProperties/genericValMultipleUpperBounds.kt b/backend.native/tests/external/codegen/blackbox/extensionProperties/genericValMultipleUpperBounds.kt new file mode 100644 index 00000000000..3f338755bd8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionProperties/genericValMultipleUpperBounds.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +import java.io.Serializable + +val T.valProp: T where T : Number, T : Serializable + get() = this + +fun box(): String { + 0.valProp + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionProperties/genericVarForPrimitiveType.kt b/backend.native/tests/external/codegen/blackbox/extensionProperties/genericVarForPrimitiveType.kt new file mode 100644 index 00000000000..a96514698c8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionProperties/genericVarForPrimitiveType.kt @@ -0,0 +1,40 @@ +var T.varProp: T + get() = this + set(value: T) {} + +class A { + var int: Int = 0 + var long: Long = 0.toLong() + var short: Short = 0.toShort() + var byte: Byte = 0.toByte() + var double: Double = 0.0 + var float: Float = 0.0f + var char: Char = '0' + var bool: Boolean = false + + operator fun invoke() { + int.varProp = int + long.varProp = long + short.varProp = short + byte.varProp = byte + double.varProp = double + float.varProp = float + char.varProp = char + bool.varProp = bool + } +} + +fun box(): String { + 0.varProp = 0 + false.varProp = false + '0'.varProp = '0' + 0.0.varProp = 0.0 + 0.0f.varProp = 0.0f + 0.toByte().varProp = 0.toByte() + 0.toShort().varProp = 0.toShort() + 0.toLong().varProp = 0.toLong() + + A()() + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/extensionProperties/inClass.kt b/backend.native/tests/external/codegen/blackbox/extensionProperties/inClass.kt new file mode 100644 index 00000000000..7f1d8387e59 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionProperties/inClass.kt @@ -0,0 +1,12 @@ +class Test { + val Int.foo: String + get() = "OK" + + fun test(): String { + return 1.foo + } +} + +fun box(): String { + return Test().test() +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionProperties/inClassLongTypeInReceiver.kt b/backend.native/tests/external/codegen/blackbox/extensionProperties/inClassLongTypeInReceiver.kt new file mode 100644 index 00000000000..f4a3c12530b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionProperties/inClassLongTypeInReceiver.kt @@ -0,0 +1,28 @@ +class Test { + var doubleStorage = "fail" + var longStorage = "fail" + + var Double.foo: String + get() = doubleStorage + set(value) { + doubleStorage = value + } + + var Long.bar: String + get() = longStorage + set(value) { + longStorage = value + } + + fun test(): String { + val d = 1.0 + d.foo = "O" + val l = 1L + l.bar = "K" + return d.foo + l.bar + } +} + +fun box(): String { + return Test().test() +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionProperties/inClassWithGetter.kt b/backend.native/tests/external/codegen/blackbox/extensionProperties/inClassWithGetter.kt new file mode 100644 index 00000000000..e14ca8e686f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionProperties/inClassWithGetter.kt @@ -0,0 +1,14 @@ +class Test { + val Int.foo: String + get() { + return "OK" + } + + fun test(): String { + return 1.foo + } +} + +fun box(): String { + return Test().test() +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionProperties/inClassWithPrivateGetter.kt b/backend.native/tests/external/codegen/blackbox/extensionProperties/inClassWithPrivateGetter.kt new file mode 100644 index 00000000000..b16ace4a6f0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionProperties/inClassWithPrivateGetter.kt @@ -0,0 +1,14 @@ +class Test { + private val Int.foo: String + get() { + return "OK" + } + + fun test(): String { + return 1.foo + } +} + +fun box(): String { + return Test().test() +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionProperties/inClassWithPrivateSetter.kt b/backend.native/tests/external/codegen/blackbox/extensionProperties/inClassWithPrivateSetter.kt new file mode 100644 index 00000000000..de02691a5ac --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionProperties/inClassWithPrivateSetter.kt @@ -0,0 +1,19 @@ +class Test { + var storage = "Fail" + + var Int.foo: String + get() = storage + private set(str: String) { + storage = str + } + + fun test(): String { + val i = 1 + i.foo = "OK" + return i.foo + } +} + +fun box(): String { + return Test().test() +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionProperties/inClassWithSetter.kt b/backend.native/tests/external/codegen/blackbox/extensionProperties/inClassWithSetter.kt new file mode 100644 index 00000000000..c562b29e92e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionProperties/inClassWithSetter.kt @@ -0,0 +1,19 @@ +class Test { + var storage = "Fail" + + var Int.foo: String + get() = storage + set(value) { + storage = value + } + + fun test(): String { + val i = 1 + i.foo = "OK" + return i.foo + } +} + +fun box(): String { + return Test().test() +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionProperties/kt9897.kt b/backend.native/tests/external/codegen/blackbox/extensionProperties/kt9897.kt new file mode 100644 index 00000000000..728323b1c64 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionProperties/kt9897.kt @@ -0,0 +1,41 @@ +object Test { + var z = "0" + var l = 0L + + fun changeObject(): String { + "1".someProperty += 1 + return z + } + + fun changeLong(): Long { + 2L.someProperty -= 1 + return l + } + + var String.someProperty: Int + get() { + return this.length + } + set(left) { + z += this + left + } + + var Long.someProperty: Long + get() { + return l + } + set(left) { + l += this + left + } + +} + +fun box(): String { + val changeObject = Test.changeObject() + if (changeObject != "012") return "fail 1: $changeObject" + + val changeLong = Test.changeLong() + if (changeLong != 1L) return "fail 1: $changeLong" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/extensionProperties/kt9897_topLevel.kt b/backend.native/tests/external/codegen/blackbox/extensionProperties/kt9897_topLevel.kt new file mode 100644 index 00000000000..9ff0dd42c22 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionProperties/kt9897_topLevel.kt @@ -0,0 +1,38 @@ +var z = "0" +var l = 0L + +fun changeObject(): String { + "1".someProperty += 1 + return z +} + +fun changeLong(): Long { + 2L.someProperty -= 1 + return l +} + +var String.someProperty: Int + get() { + return this.length + } + set(left) { + z += this + left + } + +var Long.someProperty: Long + get() { + return l + } + set(left) { + l += this + left + } + +fun box(): String { + val changeObject = changeObject() + if (changeObject != "012") return "fail 1: $changeObject" + + val changeLong = changeLong() + if (changeLong != 1L) return "fail 1: $changeLong" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/extensionProperties/topLevel.kt b/backend.native/tests/external/codegen/blackbox/extensionProperties/topLevel.kt new file mode 100644 index 00000000000..df0abcea24e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionProperties/topLevel.kt @@ -0,0 +1,6 @@ +val Int.foo: String + get() = "OK" + +fun box(): String { + return 1.foo +} diff --git a/backend.native/tests/external/codegen/blackbox/extensionProperties/topLevelLongTypeInReceiver.kt b/backend.native/tests/external/codegen/blackbox/extensionProperties/topLevelLongTypeInReceiver.kt new file mode 100644 index 00000000000..b00288453a2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/extensionProperties/topLevelLongTypeInReceiver.kt @@ -0,0 +1,22 @@ +var fooStorage = "Fail" +var barStorage = "Fail" + +var Double.foo: String + get() = fooStorage + set(value) { + fooStorage = value + } + +var Long.bar: String + get() = barStorage + set(value) { + barStorage = value + } + +fun box(): String { + val d = 1.0 + d.foo = "O" + val l = 1L + l.bar = "K" + return d.foo + l.bar +} diff --git a/backend.native/tests/external/codegen/blackbox/external/jvmStaticExternal.kt b/backend.native/tests/external/codegen/blackbox/external/jvmStaticExternal.kt new file mode 100644 index 00000000000..6fbc3f124df --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/external/jvmStaticExternal.kt @@ -0,0 +1,37 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +package foo + +class WithNative { + companion object { + @JvmStatic external fun bar(l: Long, s: String): Double + } +} + +object ObjWithNative { + @JvmStatic external fun bar(l: Long, s: String): Double +} + +fun box(): String { + var d = 0.0 + try { + d = WithNative.bar(1, "") + return "Link error expected" + } + catch (e: java.lang.UnsatisfiedLinkError) { + if (e.message != "foo.WithNative.bar(JLjava/lang/String;)D") return "Fail 1: " + e.message + } + + try { + d = ObjWithNative.bar(1, "") + return "Link error expected on object" + } + catch (e: java.lang.UnsatisfiedLinkError) { + if (e.message != "foo.ObjWithNative.bar(JLjava/lang/String;)D") return "Fail 2: " + e.message + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/external/jvmStaticExternalPrivate.kt b/backend.native/tests/external/codegen/blackbox/external/jvmStaticExternalPrivate.kt new file mode 100644 index 00000000000..125d7eb8ed2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/external/jvmStaticExternalPrivate.kt @@ -0,0 +1,27 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +class C { + companion object { + private @JvmStatic external fun foo() + } + + fun bar() { + foo() + } +} + +fun box(): String { + try { + C().bar() + return "Link error expected" + } + catch (e: java.lang.UnsatisfiedLinkError) { + if (e.message != "C.foo()V") return "Fail 1: " + e.message + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/external/withDefaultArg.kt b/backend.native/tests/external/codegen/blackbox/external/withDefaultArg.kt new file mode 100644 index 00000000000..5cda0c9c789 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/external/withDefaultArg.kt @@ -0,0 +1,44 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +package foo + +object ObjWithNative { + external fun foo(x: Int = 1): Double + + @JvmStatic external fun bar(l: Long, s: String = ""): Double +} + +external fun topLevel(x: Int = 1): Double + +fun box(): String { + var d = 0.0 + + try { + d = ObjWithNative.bar(1) + return "Link error expected on object" + } + catch (e: java.lang.UnsatisfiedLinkError) { + if (e.message != "foo.ObjWithNative.bar(JLjava/lang/String;)D") return "Fail 1: " + e.message + } + + try { + d = ObjWithNative.foo() + return "Link error expected on object" + } + catch (e: java.lang.UnsatisfiedLinkError) { + if (e.message != "foo.ObjWithNative.foo(I)D") return "Fail 2: " + e.message + } + + try { + d = topLevel() + return "Link error expected on object" + } + catch (e: java.lang.UnsatisfiedLinkError) { + if (e.message != "foo.WithDefaultArgKt.topLevel(I)D") return "Fail 3: " + e.message + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/fakeOverride/diamondFunction.kt b/backend.native/tests/external/codegen/blackbox/fakeOverride/diamondFunction.kt new file mode 100644 index 00000000000..da73cd28d7f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/fakeOverride/diamondFunction.kt @@ -0,0 +1,31 @@ +interface T { + fun foo(): Unit +} + +open class A : T { + override fun foo() {} +} + +interface B : T + +class C : A(), B +class D : B, A() +class E : A(), B, T +class F : B, A(), T +class G : A(), T, B +class H : B, T, A() +class I : T, A(), B +class J : T, B, A() + +fun box(): String { + C().foo() + D().foo() + E().foo() + F().foo() + G().foo() + H().foo() + I().foo() + J().foo() + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/fakeOverride/function.kt b/backend.native/tests/external/codegen/blackbox/fakeOverride/function.kt new file mode 100644 index 00000000000..af0e02f4f49 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/fakeOverride/function.kt @@ -0,0 +1,35 @@ +interface T { + fun foo(): Unit +} + +open class A : T { + override fun foo(): Unit {} +} + +class B : A(), T +class C : T, A() + +interface U : T +class D : U, A() +class E : A(), U +class F : U, T, A() +class G : T, U, A() +class H : U, A(), T +class I : T, A(), U +class J : A(), U, T +class K : A(), T, U + +fun box(): String { + B().foo() + C().foo() + D().foo() + E().foo() + F().foo() + G().foo() + H().foo() + I().foo() + J().foo() + K().foo() + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/fakeOverride/propertyGetter.kt b/backend.native/tests/external/codegen/blackbox/fakeOverride/propertyGetter.kt new file mode 100644 index 00000000000..c032e3ab837 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/fakeOverride/propertyGetter.kt @@ -0,0 +1,37 @@ +interface T { + val foo: String +} + +open class A : T { + override val foo: String = "" +} + +class B : A(), T +class C : T, A() + +interface U : T + +class D : U, A() +class E : A(), U +class F : U, T, A() +class G : T, U, A() +class H : U, A(), T +class I : T, A(), U +class J : A(), U, T +class K : A(), T, U + +fun box(): String { + B().foo + C().foo + + D().foo + E().foo + F().foo + G().foo + H().foo + I().foo + J().foo + K().foo + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/fakeOverride/propertySetter.kt b/backend.native/tests/external/codegen/blackbox/fakeOverride/propertySetter.kt new file mode 100644 index 00000000000..c2f623ba448 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/fakeOverride/propertySetter.kt @@ -0,0 +1,18 @@ +interface T { + var result: String +} + +open class A : T { + override var result: String + get() = "" + set(value) {} +} + +class B : A(), T +class C : T, A() + +fun box(): String { + B().result = "" + C().result = "" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/fieldRename/constructorAndClassObject.kt b/backend.native/tests/external/codegen/blackbox/fieldRename/constructorAndClassObject.kt new file mode 100644 index 00000000000..7bf67aa45a1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/fieldRename/constructorAndClassObject.kt @@ -0,0 +1,16 @@ +class Test(val prop: String) { + + companion object { + public val prop : String = "CO"; + } + +} + + +fun box() : String { + val obj = Test("OK"); + + if (Test.prop != "CO") return "fail1"; + + return obj.prop; +} diff --git a/backend.native/tests/external/codegen/blackbox/fieldRename/delegates.kt b/backend.native/tests/external/codegen/blackbox/fieldRename/delegates.kt new file mode 100644 index 00000000000..83501722a0e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/fieldRename/delegates.kt @@ -0,0 +1,28 @@ +import kotlin.reflect.KProperty + +public open class TestDelegate(private val initializer: () -> T) { + private var value: T? = null + + operator open fun getValue(thisRef: Any?, desc: KProperty<*>): T { + if (value == null) { + value = initializer() + } + return value!! + } + + operator open fun setValue(thisRef: Any?, desc: KProperty<*>, svalue : T) { + value = svalue + } +} + +class A {} +class B {} + +public val A.s: String by TestDelegate( {"OK2"}) +public val B.s: String by TestDelegate( {"OK"}) + +fun box() : String { + if (A().s != "OK2") return "fail1" + + return B().s +} diff --git a/backend.native/tests/external/codegen/blackbox/fieldRename/genericPropertyWithItself.kt b/backend.native/tests/external/codegen/blackbox/fieldRename/genericPropertyWithItself.kt new file mode 100644 index 00000000000..ea584c3a917 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/fieldRename/genericPropertyWithItself.kt @@ -0,0 +1,14 @@ +public class MPair ( + public val first: A +) { + override fun equals(o: Any?): Boolean { + val t = o as MPair<*> + return first == t.first + } +} + +fun box(): String { + val a = MPair("O") + a.equals(a) + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/finally/finallyAndFinally.kt b/backend.native/tests/external/codegen/blackbox/finally/finallyAndFinally.kt new file mode 100644 index 00000000000..e902bc8746f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/finally/finallyAndFinally.kt @@ -0,0 +1,39 @@ +class MyString { + var s = "" + operator fun plus(x : String) : MyString { + s += x + return this + } + + override fun toString(): String { + return s + } +} + + +fun test1() : MyString { + var r = MyString() + try { + r + "Try1" + + try { + r + "Try2" + if (true) + return r + } finally { + r + "Finally2" + if (true) { + return r + } + } + + return r + } finally { + r + "Finally1" + } +} + + +fun box(): String { + return if (test1().toString() == "Try1Try2Finally2Finally1") "OK" else "fail: ${test1()}" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/finally/kt3549.kt b/backend.native/tests/external/codegen/blackbox/finally/kt3549.kt new file mode 100644 index 00000000000..8e6f09f2aff --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/finally/kt3549.kt @@ -0,0 +1,41 @@ +fun test1() : String { + var s = ""; + try { + try { + s += "Try"; + throw Exception() + } catch (x : Exception) { + s += "Catch"; + throw x + } finally { + s += "Finally"; + } + } catch (x : Exception) { + return s + } +} + +fun test2() : String { + var s = ""; + + try { + s += "Try"; + throw Exception() + } catch (x : Exception) { + s += "Catch"; + } finally { + s += "Finally"; + } + + return s +} + + + +fun box() : String { + if (test1() != "TryCatchFinally") return "fail1: ${test1()}" + + if (test2() != "TryCatchFinally") return "fail2: ${test2()}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/finally/kt3706.kt b/backend.native/tests/external/codegen/blackbox/finally/kt3706.kt new file mode 100644 index 00000000000..923e3aa045a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/finally/kt3706.kt @@ -0,0 +1,16 @@ +fun f(): Int { + try { + return 0 + } + finally { + try { // culprit ?? remove this try-catch and it works. + } catch (ignore: Exception) { + } + } +} + +fun box(): String { + if (f() != 0) return "fail1" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/finally/kt3867.kt b/backend.native/tests/external/codegen/blackbox/finally/kt3867.kt new file mode 100644 index 00000000000..8e41ea804b5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/finally/kt3867.kt @@ -0,0 +1,46 @@ +fun fail() = if (true) throw RuntimeException() else 1 + +fun test1(): String { + var r = "" + try { + try { + r += "Try" + return r + } catch (e: RuntimeException) { + r += "Catch" + return r + } + finally { + r += "Finally" + fail() + } + } catch (e: RuntimeException) { + return r + } +} + +fun test2(): String { + var r = "" + try { + try { + r += "Try" + } catch (e: RuntimeException) { + r += "Catch" + } + finally { + r += "Finally" + fail() + } + } catch (e: RuntimeException) { + return r + } + return r + "Fail" +} + +fun box(): String { + if (test1() != "TryFinally") return "fail1: ${test1()}" + + if (test2() != "TryFinally") return "fail2: ${test2()}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/finally/kt3874.kt b/backend.native/tests/external/codegen/blackbox/finally/kt3874.kt new file mode 100644 index 00000000000..fa0a4259d12 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/finally/kt3874.kt @@ -0,0 +1,35 @@ +fun test1(): String { + var r = "" + for (i in 1..2) { + try { + r += "O" + continue + } finally { + r += "K" + break + } + } + return r +} + +fun test2(): String { + var r = "" + for (i in 1..2) { + try { + r += "O" + break + } finally { + r += "K" + continue + } + } + return r +} + +fun box(): String { + if (test1() != "OK") return "fail1: ${test1()}" + + if (test2() != "OKOK") return "fail2: ${test2()}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/finally/kt3894.kt b/backend.native/tests/external/codegen/blackbox/finally/kt3894.kt new file mode 100644 index 00000000000..83930d88fbd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/finally/kt3894.kt @@ -0,0 +1,36 @@ +class MyString { + var s = "" + operator fun plus(x : String) : MyString { + s += x + return this + } + + override fun toString(): String { + return s + } +} + +fun test1() : MyString { + var r = MyString() + while (true) { + try { + r + "Try" + + if (true) { + r + "Break" + break + } + + } finally { + return r + "Finally" + } + } +} + + + +fun box(): String { + if (test1().toString() != "TryBreakFinally") return "fail1: ${test1().toString()}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/finally/kt4134.kt b/backend.native/tests/external/codegen/blackbox/finally/kt4134.kt new file mode 100644 index 00000000000..24e4750d089 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/finally/kt4134.kt @@ -0,0 +1,15 @@ +fun io(s: R, a: (R) -> T): T { + try { + return a(s) + } finally { + try { + s.toString() + } catch(e: Exception) { + //NOP + } + } +} + +fun box() : String { + return io(("OK"), {it}) +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/finally/loopAndFinally.kt b/backend.native/tests/external/codegen/blackbox/finally/loopAndFinally.kt new file mode 100644 index 00000000000..88425e55ac0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/finally/loopAndFinally.kt @@ -0,0 +1,69 @@ +//KT-3869 Loops and finally: outer finally block not run + +class MyString { + var s = "" + operator fun plus(x : String) : MyString { + s += x + return this + } + + override fun toString(): String { + return s + } +} + +fun test1() : MyString { + var r = MyString() + try { + r + "Try" + + while(r.toString() != "") { + return r + "Loop" + } + + return r + "Fail" + } finally { + r + "Finally" + } +} + +fun test2() : MyString { + var r = MyString() + try { + r + "Try" + + do { + if (r.toString() != "") { + return r + "Loop" + } + } while (r.toString() != "") + + return r + "Fail" + } finally { + r + "Finally" + } +} + +fun test3() : MyString { + var r = MyString() + try { + r + "Try" + + for(i in 1..2) { + r + "Loop" + return r + } + + return r + "Fail" + } finally { + r + "Finally" + } +} + +fun box(): String { + if (test1().toString() != "TryLoopFinally") return "fail1: ${test1()}" + if (test2().toString() != "TryLoopFinally") return "fail2: ${test2()}" + if (test3().toString() != "TryLoopFinally") return "fail3: ${test3()}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/finally/notChainCatch.kt b/backend.native/tests/external/codegen/blackbox/finally/notChainCatch.kt new file mode 100644 index 00000000000..18e5573b318 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/finally/notChainCatch.kt @@ -0,0 +1,98 @@ +fun unsupportedEx() { + if (true) throw UnsupportedOperationException() +} + +fun runtimeEx() { + if (true) throw RuntimeException() +} + +fun test1() : String { + var s = ""; + try { + try { + s += "Try"; + unsupportedEx() + } catch (x : UnsupportedOperationException) { + s += "Catch"; + runtimeEx() + } catch (e: RuntimeException) { + s += "WrongCatch" + } + } catch (x : RuntimeException) { + return s + } + return s + "Failed" +} + +fun test1WithFinally() : String { + var s = ""; + try { + try { + s += "Try"; + unsupportedEx() + } catch (x : UnsupportedOperationException) { + s += "Catch"; + runtimeEx() + } catch (e: RuntimeException) { + s += "WrongCatch" + } finally { + s += "Finally" + } + } catch (x : RuntimeException) { + return s + } + return s + "Failed" +} + +fun test2() : String { + var s = ""; + try { + try { + s += "Try"; + unsupportedEx() + return s + } catch (x : UnsupportedOperationException) { + s += "Catch"; + runtimeEx() + return s + } catch (e: RuntimeException) { + s += "WrongCatch" + } + } catch (x : RuntimeException) { + return s + } + return s + "Failed" +} + +fun test2WithFinally() : String { + var s = ""; + try { + try { + s += "Try"; + unsupportedEx() + return s + } catch (x : UnsupportedOperationException) { + s += "Catch"; + runtimeEx() + return s + } catch (e: RuntimeException) { + s += "WrongCatch" + } finally { + s += "Finally" + } + } catch (x : RuntimeException) { + return s + } + return s + "Failed" +} + + + +fun box() : String { + if (test1() != "TryCatch") return "fail1: ${test1()}" + if (test1WithFinally() != "TryCatchFinally") return "fail2: ${test1WithFinally()}" + + if (test2() != "TryCatch") return "fail3: ${test2()}" + if (test2WithFinally() != "TryCatchFinally") return "fail4: ${test2WithFinally()}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/finally/tryFinally.kt b/backend.native/tests/external/codegen/blackbox/finally/tryFinally.kt new file mode 100644 index 00000000000..39928fbec60 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/finally/tryFinally.kt @@ -0,0 +1,45 @@ +fun unsupportedEx() { + if (true) throw UnsupportedOperationException() +} + +fun runtimeEx() { + if (true) throw RuntimeException() +} + +fun test1WithFinally() : String { + var s = ""; + try { + try { + s += "Try"; + unsupportedEx() + } finally { + s += "Finally" + } + } catch (x : RuntimeException) { + return s + } + return s + "Failed" +} + + +fun test2WithFinally() : String { + var s = ""; + try { + try { + s += "Try"; + unsupportedEx() + return s + } finally { + s += "Finally" + } + } catch (x : RuntimeException) { + return s + } +} + +fun box() : String { + if (test1WithFinally() != "TryFinally") return "fail2: ${test1WithFinally()}" + + if (test2WithFinally() != "TryFinally") return "fail4: ${test2WithFinally()}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/finally/tryLoopTry.kt b/backend.native/tests/external/codegen/blackbox/finally/tryLoopTry.kt new file mode 100644 index 00000000000..0a969975070 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/finally/tryLoopTry.kt @@ -0,0 +1,36 @@ +//test for appropriate + +class MyString { + var s = "" + operator fun plus(x : String) : MyString { + s += x + return this + } + + override fun toString(): String { + return s + } +} + + +fun test1() : MyString { + var r = MyString() + try { + r + "Try1" + for(i in 1..1) { + try { + r + "Try2" + } finally { + return r + "Finally2" + } + } + + } finally { + r + "Finally1" + } + return r + "Fail" +} + +fun box(): String { + return if (test1().toString() == "Try1Try2Finally2Finally1") "OK" else "fail: ${test1()}" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/fullJdk/charBuffer.kt b/backend.native/tests/external/codegen/blackbox/fullJdk/charBuffer.kt new file mode 100644 index 00000000000..7d7f2702e91 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/fullJdk/charBuffer.kt @@ -0,0 +1,13 @@ +// TARGET_BACKEND: JVM + +// FULL_JDK + +import java.nio.CharBuffer + +fun box(): String { + val cb = CharBuffer.wrap("OK") + cb.position(1) + val o = cb[0] + val k = (cb as CharSequence).get(0) + return o.toString() + k +} diff --git a/backend.native/tests/external/codegen/blackbox/fullJdk/classpath.kt b/backend.native/tests/external/codegen/blackbox/fullJdk/classpath.kt new file mode 100644 index 00000000000..6277a2ffc6c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/fullJdk/classpath.kt @@ -0,0 +1,18 @@ +// TARGET_BACKEND: JVM + +// FULL_JDK + +import sun.nio.cs.ext.Big5 +import sun.net.spi.nameservice.dns.DNSNameService +import javax.crypto.Cipher +import com.sun.crypto.provider.SunJCE +import sun.nio.ByteBuffered + +fun box(): String { + val a = Big5() // charsets.jar + val c = DNSNameService() // dnsns.ajr + val e : Cipher? = null // jce.jar + val f : SunJCE? = null // sunjce_provider.jar + val j : ByteBuffered? = null // rt.jar + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/fullJdk/ifInWhile.kt b/backend.native/tests/external/codegen/blackbox/fullJdk/ifInWhile.kt new file mode 100644 index 00000000000..8831f244021 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/fullJdk/ifInWhile.kt @@ -0,0 +1,15 @@ +// TARGET_BACKEND: JVM + +// FULL_JDK + +fun box() : String { + val processors = Runtime.getRuntime()!!.availableProcessors() + var threadNum = 1 + while(threadNum <= 1024) { + if(threadNum < 2 * processors) + threadNum += 1 + else + threadNum *= 2 + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/fullJdk/intCountDownLatchExtension.kt b/backend.native/tests/external/codegen/blackbox/fullJdk/intCountDownLatchExtension.kt new file mode 100644 index 00000000000..de02f10104e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/fullJdk/intCountDownLatchExtension.kt @@ -0,0 +1,25 @@ +// TARGET_BACKEND: JVM + +// FULL_JDK + +import java.util.concurrent.atomic.AtomicInteger +import java.util.concurrent.CountDownLatch +import java.util.concurrent.locks.ReentrantLock + +fun Int.latch(op: CountDownLatch.() -> T) : T { + val cdl = CountDownLatch(this) + val res = cdl.op() + cdl.await() + return res +} + +fun id(op: () -> Unit) = op() + +fun box() : String { + 1.latch{ + id { + countDown() + } + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/fullJdk/kt434.kt b/backend.native/tests/external/codegen/blackbox/fullJdk/kt434.kt new file mode 100644 index 00000000000..1037c13e217 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/fullJdk/kt434.kt @@ -0,0 +1,17 @@ +// TARGET_BACKEND: JVM + +// FULL_JDK + +import java.net.* + +fun String.decodeURI(encoding : String) : String? = + try { + URLDecoder.decode(this, encoding) + } + catch (e : Throwable) { + null + } + +fun box() : String { + return if("hhh".decodeURI("") == null) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/fullJdk/native/nativePropertyAccessors.kt b/backend.native/tests/external/codegen/blackbox/fullJdk/native/nativePropertyAccessors.kt new file mode 100644 index 00000000000..56140cace52 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/fullJdk/native/nativePropertyAccessors.kt @@ -0,0 +1,54 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FULL_JDK + +class C { + companion object { + val defaultGetter: Int = 1 + external get + + var defaultSetter: Int = 1 + external get + external set + } + + val defaultGetter: Int = 1 + external get + + var defaultSetter: Int = 1 + external get + external set +} + +val defaultGetter: Int = 1 + external get + +var defaultSetter: Int = 1 + external get + external set + +fun check(body: () -> Unit, signature: String): String? { + try { + body() + return "Link error expected" + } + catch (e: java.lang.UnsatisfiedLinkError) { + if (e.message != signature) return "Fail $signature: " + e.message + } + + return null +} + +fun box(): String { + return check({defaultGetter}, "NativePropertyAccessorsKt.getDefaultGetter()I") + ?: check({defaultSetter = 1}, "NativePropertyAccessorsKt.setDefaultSetter(I)V") + + ?: check({C.defaultGetter}, "C\$Companion.getDefaultGetter()I") + ?: check({C.defaultSetter = 1}, "C\$Companion.setDefaultSetter(I)V") + + ?: check({C().defaultGetter}, "C.getDefaultGetter()I") + ?: check({C().defaultSetter = 1}, "C.setDefaultSetter(I)V") + + ?: "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/fullJdk/native/simpleNative.kt b/backend.native/tests/external/codegen/blackbox/fullJdk/native/simpleNative.kt new file mode 100644 index 00000000000..94b2a5e8e52 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/fullJdk/native/simpleNative.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FULL_JDK + +package foo + +class WithNative { + external fun foo() +} + +fun box(): String { + try { + WithNative().foo() + return "Link error expected" + } + catch (e: java.lang.UnsatisfiedLinkError) { + return "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/fullJdk/native/topLevel.kt b/backend.native/tests/external/codegen/blackbox/fullJdk/native/topLevel.kt new file mode 100644 index 00000000000..aa675eef76c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/fullJdk/native/topLevel.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FULL_JDK + +package foo + +external fun bar(l: Long, s: String): Double + +fun box(): String { + var d = 0.0 + + try { + d = bar(1, "") + return "Link error expected on object" + } + catch (e: java.lang.UnsatisfiedLinkError) { + if (e.message != "foo.TopLevelKt.bar(JLjava/lang/String;)D") return "Fail 1: " + e.message + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/fullJdk/platformTypeAssertionStackTrace.kt b/backend.native/tests/external/codegen/blackbox/fullJdk/platformTypeAssertionStackTrace.kt new file mode 100644 index 00000000000..b61651eedad --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/fullJdk/platformTypeAssertionStackTrace.kt @@ -0,0 +1,24 @@ +// TARGET_BACKEND: JVM + +// FULL_JDK + +import java.util.* + +fun box(): String { + val a = ArrayList() as AbstractList + a.add(null) + try { + val b: String = a[0] + return "Fail: an exception should be thrown" + } catch (e: IllegalStateException) { + val st = (e as java.lang.Throwable).getStackTrace() + if (st.size < 5) { + return "Fail: very small stack trace, should at least have current function and JUnit reflective calls: ${Arrays.toString(st)}" + } + val top = st[0] + if (!(top.getClassName() == "PlatformTypeAssertionStackTraceKt" && top.getMethodName() == "box")) { + return "Fail: top stack trace element should be PlatformTypeAssertionStackTraceKt.box() from default package, but was $top" + } + return "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/fullJdk/regressions/kt1770.kt b/backend.native/tests/external/codegen/blackbox/fullJdk/regressions/kt1770.kt new file mode 100644 index 00000000000..aceeec091bb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/fullJdk/regressions/kt1770.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FULL_JDK + +import org.w3c.dom.Element +import org.xml.sax.InputSource +import javax.xml.parsers.DocumentBuilderFactory +import java.io.StringReader + +class MyElement(e: Element): Element by e { + fun bar() = "OK" +} + +fun box() : String { + val factory = DocumentBuilderFactory.newInstance()!!; + val builder = factory.newDocumentBuilder()!!; + val source = InputSource(StringReader("")); + val doc = builder.parse(source)!!; + val myElement = MyElement(doc.getDocumentElement()!!) + return myElement.getTagName()!! +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/coerceVoidToArray.kt b/backend.native/tests/external/codegen/blackbox/functions/coerceVoidToArray.kt new file mode 100644 index 00000000000..695a3a50187 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/coerceVoidToArray.kt @@ -0,0 +1,16 @@ +fun a(): IntArray? = null + +fun b(): Nothing = throw Exception() + +fun foo(): IntArray = a() ?: b() + + +fun box(): String { + try { + foo() + } catch (e: Exception) { + return "OK" + } + + return "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/coerceVoidToObject.kt b/backend.native/tests/external/codegen/blackbox/functions/coerceVoidToObject.kt new file mode 100644 index 00000000000..660ea0d44ec --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/coerceVoidToObject.kt @@ -0,0 +1,16 @@ +fun a(): String? = null + +fun b(): Nothing = throw Exception() + +fun foo(): String = a() ?: b() + + +fun box(): String { + try { + foo() + } catch (e: Exception) { + return "OK" + } + + return "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/dataLocalVariable.kt b/backend.native/tests/external/codegen/blackbox/functions/dataLocalVariable.kt new file mode 100644 index 00000000000..4d3c84e1085 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/dataLocalVariable.kt @@ -0,0 +1,8 @@ +// TODO: Enable when JS backend gets support of Java class library +// IGNORE_BACKEND: JS, NATIVE +fun ok(b: Boolean) = if (b) "OK" else "Fail" + +fun box(): String { + val data = java.util.Arrays.asList("foo", "bar")!! + return ok(data.contains("foo")) +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/defaultargs.kt b/backend.native/tests/external/codegen/blackbox/functions/defaultargs.kt new file mode 100644 index 00000000000..726a4d4db10 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/defaultargs.kt @@ -0,0 +1,12 @@ +open abstract class B { + fun foo(arg: Int = 239 + 1) : Int = arg +} + +class C() : B() { +} + +fun box() : String { + if(C().foo(10) != 10) return "fail" + if(C().foo() != 240) return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/defaultargs1.kt b/backend.native/tests/external/codegen/blackbox/functions/defaultargs1.kt new file mode 100644 index 00000000000..5666dd5603d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/defaultargs1.kt @@ -0,0 +1,10 @@ +fun T.toPrefixedString(prefix: String = "", suffix: String="") = prefix + this.toString() + suffix + +fun box() : String { + if("mama".toPrefixedString(suffix="321", prefix="papa") != "papamama321") return "fail" + if("mama".toPrefixedString(prefix="papa") != "papamama") return "fail" + if("mama".toPrefixedString("papa", "239") != "papamama239") return "fail" + if("mama".toPrefixedString("papa") != "papamama") return "fail" + if("mama".toPrefixedString() != "mama") return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/defaultargs2.kt b/backend.native/tests/external/codegen/blackbox/functions/defaultargs2.kt new file mode 100644 index 00000000000..710cc126ad2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/defaultargs2.kt @@ -0,0 +1,34 @@ +class T4( + val c1: Boolean, + val c2: Boolean, + val c3: Boolean, + val c4: String +) { + override fun equals(o: Any?): Boolean { + if (o !is T4) return false; + return c1 == o.c1 && + c2 == o.c2 && + c3 == o.c3 && + c4 == o.c4 + } +} + +fun reformat( + str : String, + normalizeCase : Boolean = true, + uppercaseFirstLetter : Boolean = true, + divideByCamelHumps : Boolean = true, + wordSeparator : String = " " +) = + T4(normalizeCase, uppercaseFirstLetter, divideByCamelHumps, wordSeparator) + + +fun box() : String { + val expected = T4(true, true, true, " ") + if(reformat("", true, true, true, " ") != expected) return "fail" + if(reformat("", true, true, true) != expected) return "fail" + if(reformat("", true, true) != expected) return "fail" + if(reformat("", true) != expected) return "fail" + if(reformat("") != expected) return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/defaultargs3.kt b/backend.native/tests/external/codegen/blackbox/functions/defaultargs3.kt new file mode 100644 index 00000000000..df755765779 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/defaultargs3.kt @@ -0,0 +1,15 @@ + +class C() { + fun Any.toMyPrefixedString(prefix: String = "", suffix: String="") : String = prefix + " " + suffix + + fun testReceiver() : String { + val res : String = "mama".toMyPrefixedString("111", "222") + return res + } + +} + +fun box() : String { + if(C().testReceiver() != "111 222") return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/defaultargs4.kt b/backend.native/tests/external/codegen/blackbox/functions/defaultargs4.kt new file mode 100644 index 00000000000..b98b9a95d64 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/defaultargs4.kt @@ -0,0 +1,19 @@ +interface A { + fun bar2(arg: Int = 239) : Int + + fun bar(arg: Int = 240) : Int = bar2(arg/2) +} + +open abstract class B : A { + override fun bar2(arg: Int) : Int = arg +} + +class C : B() + +fun box() : String { + if(C().bar(10) != 5) return "fail" + if(C().bar() != 120) return "fail" + if(C().bar2() != 239) return "fail" + if(C().bar2(10) != 10) return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/defaultargs5.kt b/backend.native/tests/external/codegen/blackbox/functions/defaultargs5.kt new file mode 100644 index 00000000000..91dc6f6be40 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/defaultargs5.kt @@ -0,0 +1,13 @@ +open abstract class B { + abstract fun foo2(arg: Int = 239) : Int +} + +class C : B() { + override fun foo2(arg: Int) : Int = arg +} + +fun box() : String { + if(C().foo2() != 239) return "fail" + if(C().foo2(10) != 10) return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/defaultargs6.kt b/backend.native/tests/external/codegen/blackbox/functions/defaultargs6.kt new file mode 100644 index 00000000000..90c4e943d5d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/defaultargs6.kt @@ -0,0 +1,7 @@ +interface A { + fun foo(x: Int, y: Int = x + 20, z: Int = y * 2) = z +} + +class B : A {} + +fun box() = if (B().foo(1) == 42) "OK" else "Fail" diff --git a/backend.native/tests/external/codegen/blackbox/functions/defaultargs7.kt b/backend.native/tests/external/codegen/blackbox/functions/defaultargs7.kt new file mode 100644 index 00000000000..107929fad00 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/defaultargs7.kt @@ -0,0 +1,5 @@ +class A(val expected: Int) { + fun foo(x: Int, y: Int = x + 20, z: Int = y * 2) = z == expected +} + +fun box() = if (A(42).foo(1)) "OK" else "Fail" diff --git a/backend.native/tests/external/codegen/blackbox/functions/ea33909.kt b/backend.native/tests/external/codegen/blackbox/functions/ea33909.kt new file mode 100644 index 00000000000..f4022e8ba28 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/ea33909.kt @@ -0,0 +1,7 @@ +fun box(): String { + return justPrint(9.compareTo(4)) +} + +fun justPrint(value: Int): String { + return if (value > 0) "OK" else "Fail $value" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/fakeDescriptorWithSeveralOverridenOne.kt b/backend.native/tests/external/codegen/blackbox/functions/fakeDescriptorWithSeveralOverridenOne.kt new file mode 100644 index 00000000000..0086f8ab719 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/fakeDescriptorWithSeveralOverridenOne.kt @@ -0,0 +1,23 @@ +interface Named { + abstract fun getName() : String; +} + +interface MemberDescriptor : Named {} + +interface ClassifierDescriptor : Named {} + +interface ClassDescriptor : MemberDescriptor, ClassifierDescriptor {} + +class ClassDescriptorImpl : ClassDescriptor { + override fun getName(): String { + return "OK" + } +} + +class A(val descriptor : ClassDescriptor) { + val result : String = descriptor.getName() +} + +fun box(): String { + return A(ClassDescriptorImpl()).result +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/functionExpression/functionExpression.kt b/backend.native/tests/external/codegen/blackbox/functions/functionExpression/functionExpression.kt new file mode 100644 index 00000000000..0936de3f951 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/functionExpression/functionExpression.kt @@ -0,0 +1,32 @@ +val foo1 = fun Any.(): String { +return "239" + this +} + +val foo2 = fun Int.(i : Int) : Int = this + i + +fun fooT1() = fun (t : T) = t.toString() + +annotation class A + +fun box() : String { + if(10.foo1() != "23910") return "foo1 fail" + if(10.foo2(1) != 11) return "foo2 fail" + + if(1.(fun Int.() = this + 1)() != 2) return "test 3 failed"; + if( (fun () = 1)() != 1) return "test 4 failed"; + if( (fun (i: Int) = i)(1) != 1) return "test 5 failed"; + if( 1.(fun Int.(i: Int) = i + this)(1) != 2) return "test 6 failed"; + if( (fooT1()("mama")) != "mama") return "test 7 failed"; + + val a = @A fun Int.() = this + 1 + if (1.a() != 2) return "test 8 failed" + val b = ( fun Int.() = this + 1) + if (1.b() != 2) return "test 9 failed" + val c = (c@ fun Int.() = this + 1) + if (1.c() != 2) return "test 10 failed" + + val d = d@ fun (): Int { return@d 4} + if (d() != 4) return "test 11 failed" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/functionExpression/functionExpressionWithThisReference.kt b/backend.native/tests/external/codegen/blackbox/functions/functionExpression/functionExpressionWithThisReference.kt new file mode 100644 index 00000000000..a9e1d43173e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/functionExpression/functionExpressionWithThisReference.kt @@ -0,0 +1,34 @@ + +fun Int.thisRef1() = fun () = this +fun Int.thisRef2() = fun (): Int {return this} + +fun T.genericThisRef1() = fun () = this +fun T.genericThisRef2() = fun (): T {return this} + +val Int.valThisRef1: () -> Int get() = fun () = this +val Int.valThisRef2: () -> Int get() = fun (): Int {return this} + +val T.valGenericThisRef1: ()->T get() = fun () = this +val T.valGenericThisRef2: ()->T get() = fun (): T {return this} + +val T.withLabel1: ()->T get() = fun () = this@withLabel1 +val T.withLabel2: ()->T get() = fun (): T {return this@withLabel2} + +fun box(): String { + if (1.thisRef1()() != 1) return "Test 1 failed" + if (2.thisRef2()() != 2) return "Test 2 failed" + + if (3.genericThisRef1()() != 3) return "Test 3 failed" + if (4.genericThisRef2()() != 4) return "Test 4 failed" + + if (5.valThisRef1() != 5) return "Test 5 failed" + if (6.valThisRef2() != 6) return "Test 6 failed" + + if (7.valGenericThisRef1() != 7) return "Test 7 failed" + if (8.valGenericThisRef2() != 8) return "Test 8 failed" + + if ("bar".withLabel1() != "bar") return "Test 9 failed" + if ("bar".withLabel2() != "bar") return "Test 10 failed" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/functionExpression/functionLiteralExpression.kt b/backend.native/tests/external/codegen/blackbox/functions/functionExpression/functionLiteralExpression.kt new file mode 100644 index 00000000000..5ee7f510702 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/functionExpression/functionLiteralExpression.kt @@ -0,0 +1,27 @@ +fun Any.foo1() : ()-> String { + return { "239" + this } +} + +fun Int.foo2() : (i : Int) -> Int { + return { x -> x + this } +} + +fun fooT1(t : T) = { t.toString() } + +fun fooT2(t: T) = { x:T -> t.toString() + x.toString() } + +object t + +fun box() : String { + if( (10.foo1())() != "23910") return "foo1 fail" + if( (10.foo2())(1) != 11 ) return "foo2 fail" + + if(1.(fun Int.() = this + 1)() != 2) return "test 3 failed"; + if( {1}() != 1) return "test 4 failed"; + if( {x : Int -> x}(1) != 1) return "test 5 failed"; + if( 1.(fun Int.(x: Int) = x + this)(1) != 2) return "test 6 failed"; + if( t.(fun Any.() = this)() != t) return "test 7 failed"; + if( (fooT1("mama"))() != "mama") return "test 8 failed"; + if( (fooT2("mama"))("papa") != "mamapapa") return "test 9 failed"; + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/functionExpression/underscoreParameters.kt b/backend.native/tests/external/codegen/blackbox/functions/functionExpression/underscoreParameters.kt new file mode 100644 index 00000000000..b25ca696000 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/functionExpression/underscoreParameters.kt @@ -0,0 +1,3 @@ +fun foo(block: (String, String, String) -> String): String = block("O", "fail", "K") + +fun box() = foo(fun(x: String, _: String, y: String) = x + y) diff --git a/backend.native/tests/external/codegen/blackbox/functions/functionNtoString.kt b/backend.native/tests/external/codegen/blackbox/functions/functionNtoString.kt new file mode 100644 index 00000000000..f8c9317abcd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/functionNtoString.kt @@ -0,0 +1,38 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +fun check(expected: String, obj: Any?) { + val actual = obj.toString() + if (actual != expected) + throw AssertionError("Expected: $expected, actual: $actual") +} + +fun box(): String { + check("() -> kotlin.Unit") + { -> } + check("() -> kotlin.Int") + { -> 42 } + check("(kotlin.String) -> kotlin.Long", + fun (s: String) = 42.toLong()) + check("(kotlin.Int, kotlin.Int) -> kotlin.Unit") + { x: Int, y: Int -> } + + check("kotlin.Int.() -> kotlin.Unit", + fun Int.() {}) + check("kotlin.Unit.() -> kotlin.Int?", + fun Unit.(): Int? = 42) + check("kotlin.String.(kotlin.String?) -> kotlin.Long", + fun String.(s: String?): Long = 42.toLong()) + check("kotlin.collections.List.(kotlin.collections.MutableSet<*>, kotlin.Nothing) -> kotlin.Unit", + fun List.(x: MutableSet<*>, y: Nothing) {}) + + check("(kotlin.IntArray, kotlin.ByteArray, kotlin.ShortArray, kotlin.CharArray, kotlin.LongArray, kotlin.BooleanArray, kotlin.FloatArray, kotlin.DoubleArray) -> kotlin.Array", + fun (ia: IntArray, ba: ByteArray, sa: ShortArray, ca: CharArray, la: LongArray, za: BooleanArray, fa: FloatArray, da: DoubleArray): Array = null!!) + + check("(kotlin.Array>>>) -> kotlin.Comparable", + fun (a: Array>>>): Comparable = null!!) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/functionNtoStringGeneric.kt b/backend.native/tests/external/codegen/blackbox/functions/functionNtoStringGeneric.kt new file mode 100644 index 00000000000..0b31b944bf8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/functionNtoStringGeneric.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +fun bar(): String { + return { t: T -> t }.toString() +} + +class Baz { + fun baz(v: V): String { + return (fun(t: List): V = v).toString() + } +} + +open class Foo>(val lambda: (T) -> U) +class Bar : Foo>({ listOf(it) }) + +fun box(): String { + assertEquals("(T) -> T", bar()) + assertEquals("(kotlin.collections.List) -> V", Baz().baz("")) + assertEquals("(T) -> kotlin.collections.List", Bar().lambda.toString()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/functionNtoStringNoReflect.kt b/backend.native/tests/external/codegen/blackbox/functions/functionNtoStringNoReflect.kt new file mode 100644 index 00000000000..86b6223c050 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/functionNtoStringNoReflect.kt @@ -0,0 +1,36 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun check(expected: String, obj: Any?) { + val actual = obj.toString() + if (actual != expected) + throw AssertionError("Expected: $expected, actual: $actual") +} + +fun box(): String { + check("Function0") + { -> } + check("Function0") + { -> 42 } + check("Function1", + fun (s: String) = 42.toLong()) + check("Function2") + { x: Int, y: Int -> } + + check("Function1", + fun Int.() {}) + check("Function1", + fun Unit.(): Int? = 42) + check("Function2", + fun String.(s: String?): Long = 42.toLong()) + check("Function3, java.util.Set, ?, kotlin.Unit>", + fun List.(x: MutableSet<*>, y: Nothing) {}) + + check("Function8", + fun (ia: IntArray, ba: ByteArray, sa: ShortArray, ca: CharArray, la: LongArray, za: BooleanArray, fa: FloatArray, da: DoubleArray): Array = null!!) + + check("Function1[][][], java.lang.Comparable>", + fun (a: Array>>>): Comparable = null!!) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/infixRecursiveCall.kt b/backend.native/tests/external/codegen/blackbox/functions/infixRecursiveCall.kt new file mode 100644 index 00000000000..6670cdc54b0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/infixRecursiveCall.kt @@ -0,0 +1,8 @@ +infix fun Int.test(x : Int) : Int { + if (this > 1) { + return (this - 1) test x + } + return this +} + +fun box() : String = if (10.test(10) == 1) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/invoke/castFunctionToExtension.kt b/backend.native/tests/external/codegen/blackbox/functions/invoke/castFunctionToExtension.kt new file mode 100644 index 00000000000..34e0860840b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/invoke/castFunctionToExtension.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + val f = fun (s: String): String = s + val g = f as String.() -> String + if ("OK".g() != "OK") return "Fail 1" + + val h = fun String.(): String = this + val i = h as (String) -> String + if (i("OK") != "OK") return "Fail 2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/invoke/extensionInvokeOnExpr.kt b/backend.native/tests/external/codegen/blackbox/functions/invoke/extensionInvokeOnExpr.kt new file mode 100644 index 00000000000..35496700fd7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/invoke/extensionInvokeOnExpr.kt @@ -0,0 +1,21 @@ +class A + +class B { + operator fun A.invoke() = "##" + operator fun A.invoke(i: Int) = "#${i}" +} + +fun foo() = A() + +fun B.test(): String { + if (A()() != "##") return "fail1" + if (A()(1) != "#1") return "fail2" + if (foo()() != "##") return "fail3" + if (foo()(42) != "#42") return "fail4" + if ((foo())(42) != "#42") return "fail5" + if ({ -> A()}()() != "##") return "fail6" + if ({ -> A()}()(37) != "#37") return "fail7" + return "OK" +} + +fun box(): String = B().test() diff --git a/backend.native/tests/external/codegen/blackbox/functions/invoke/implicitInvokeInCompanionObjectWithFunctionalArgument.kt b/backend.native/tests/external/codegen/blackbox/functions/invoke/implicitInvokeInCompanionObjectWithFunctionalArgument.kt new file mode 100644 index 00000000000..f277bae8b6e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/invoke/implicitInvokeInCompanionObjectWithFunctionalArgument.kt @@ -0,0 +1,14 @@ +class TestClass { + companion object { + inline operator fun invoke(task: () -> T) = task() + } +} + +fun box(): String { + val test1 = TestClass { "K" } + if (test1 != "K") return "fail1, 'test1' == $test1" + + val ok = "OK" + + val x = TestClass { return ok } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/invoke/implicitInvokeWithFunctionLiteralArgument.kt b/backend.native/tests/external/codegen/blackbox/functions/invoke/implicitInvokeWithFunctionLiteralArgument.kt new file mode 100644 index 00000000000..de3ac9fbc73 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/invoke/implicitInvokeWithFunctionLiteralArgument.kt @@ -0,0 +1,10 @@ +class TestClass { + inline operator fun invoke(task: () -> T) = task() +} + +fun box(): String { + val test = TestClass() + val ok = "OK" + + val x = test { return ok } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/invoke/invoke.kt b/backend.native/tests/external/codegen/blackbox/functions/invoke/invoke.kt new file mode 100644 index 00000000000..15b6c093721 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/invoke/invoke.kt @@ -0,0 +1,28 @@ +package invoke + +fun test1(predicate: (Int) -> Int, i: Int) = predicate(i) + +fun test2(predicate: (Int) -> Int, i: Int) = predicate.invoke(i) + +class Method { + operator fun invoke(i: Int) = i +} + +fun test3(method: Method, i: Int) = method.invoke(i) + +fun test4(method: Method, i: Int) = method(i) + +class Method2 {} + +operator fun Method2.invoke(s: String) = s + +fun test5(method2: Method2, s: String) = method2(s) + +fun box() : String { + if (test1({ it }, 1) != 1) return "fail 1" + if (test2({ it }, 2) != 2) return "fail 2" + if (test3(Method(), 3) != 3) return "fail 3" + if (test4(Method(), 4) != 4) return "fail 4" + if (test5(Method2(), "s") != "s") return "fail5" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/invoke/invokeOnExprByConvention.kt b/backend.native/tests/external/codegen/blackbox/functions/invoke/invokeOnExprByConvention.kt new file mode 100644 index 00000000000..16e174b8db5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/invoke/invokeOnExprByConvention.kt @@ -0,0 +1,20 @@ +//KT-3217 Invoke convention after function invocation doesn't work +//KT-2728 Can't compile A()() + +class A { + operator fun invoke() = "##" + operator fun invoke(i: Int) = "#${i}" +} + +fun foo() = A() + +fun box(): String { + if (A()() != "##") return "fail1" + if (A()(1) != "#1") return "fail2" + if (foo()() != "##") return "fail3" + if (foo()(42) != "#42") return "fail4" + if ((foo())(42) != "#42") return "fail5" + if ({ -> A()}()() != "##") return "fail6" + if ({ -> A()}()(37) != "#37") return "fail7" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/invoke/invokeOnSyntheticProperty.kt b/backend.native/tests/external/codegen/blackbox/functions/invoke/invokeOnSyntheticProperty.kt new file mode 100644 index 00000000000..f96125385a1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/invoke/invokeOnSyntheticProperty.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: JavaClass.java + +public class JavaClass { + public String getO() { + return "O"; + } +} + +// FILE: main.kt + +// KT-9522 Allow invoke convention for synthetic property + +operator fun String.invoke() = this + "K" + +fun box(): String { + return JavaClass().o(); +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3189.kt b/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3189.kt new file mode 100644 index 00000000000..be9a0f42107 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3189.kt @@ -0,0 +1,15 @@ +//KT-3189 Function invoke is called with no reason + +fun box(): String { + + val bad = Bad({ 1 }) + + return if (bad.test() == 1) "OK" else "fail" +} + +class Bad(val a: () -> Int) { + + fun test(): Int = a() + + operator fun invoke(): Int = 2 +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3190.kt b/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3190.kt new file mode 100644 index 00000000000..5932544102d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3190.kt @@ -0,0 +1,26 @@ +//KT-3190 Compiler crash if function called 'invoke' calls a closure +// IGNORE_BACKEND: JS, NATIVE +// JS backend does not allow to implement Function{N} interfaces + +fun box(): String { + val test = Cached({ it + 2 }) + return if (test(1) == 3) "OK" else "fail" +} + +class Cached(private val generate: (K)->V): Function1 { + val store = HashMap() + + // Everything works just fine if 'invoke' method is renamed to, for example, 'get' + override fun invoke(p1: K) = store.getOrPut(p1) { generate(p1) } +} + +//from library +fun MutableMap.getOrPut(key: K, defaultValue: ()-> V) : V { + if (this.containsKey(key)) { + return this.get(key) as V + } else { + val answer = defaultValue() + this.put(key, answer) + return answer + } +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3297.kt b/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3297.kt new file mode 100644 index 00000000000..026ac7a3b37 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3297.kt @@ -0,0 +1,17 @@ +//KT-3297 Calling the wrong function inside an extension method to the Function0 class + +infix fun Function0.or(alt: () -> R): R { + try { + return this() + } catch (e: Exception) { + return alt() + } +} + +fun box(): String { + return { + throw RuntimeException("fail") + } or { + "OK" + } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3450getAndInvoke.kt b/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3450getAndInvoke.kt new file mode 100644 index 00000000000..012853d3a69 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3450getAndInvoke.kt @@ -0,0 +1,13 @@ +//KT-3450 get and invoke are not parsed in one expression + +public class A(val s: String) { + + operator fun get(i: Int) : A = A("$s + $i") + + operator fun invoke(builder : A.() -> String): String = builder() +} +fun x(y : String) : A = A(y) + +fun foo() = x("aaa")[42] { "$s!!" } + +fun box() = if (foo() == "aaa + 42!!") "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3631invokeOnString.kt b/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3631invokeOnString.kt new file mode 100644 index 00000000000..8f18fbcb585 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3631invokeOnString.kt @@ -0,0 +1,5 @@ +//KT-3631 String.invoke doesn't work with literals + +operator fun String.invoke(i: Int) = "$this$i" + +fun box() = if ("a"(12) == "a12") "OK" else "fail" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3772.kt b/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3772.kt new file mode 100644 index 00000000000..622f571b489 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3772.kt @@ -0,0 +1,21 @@ +//KT-3772 Invoke and overload resolution ambiguity + +open class A { + fun invoke(f: A.() -> Unit) = 1 +} + +class B { + operator fun invoke(f: B.() -> Unit) = 2 +} + +open class C +val C.attr: A get() = A() + +open class D: C() +val D.attr: B get() = B() + + +fun box(): String { + val d = D() + return if (d.attr {} == 2) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3821invokeOnThis.kt b/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3821invokeOnThis.kt new file mode 100644 index 00000000000..d15d396965a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3821invokeOnThis.kt @@ -0,0 +1,8 @@ +//KT-3821 Invoke convention doesn't work for `this` + +class A() { + operator fun invoke() = 42 + fun foo() = this() // Expecting a function type, but found A +} + +fun box() = if (A().foo() == 42) "OK" else "fail" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3822invokeOnThis.kt b/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3822invokeOnThis.kt new file mode 100644 index 00000000000..531f9f79450 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/invoke/kt3822invokeOnThis.kt @@ -0,0 +1,11 @@ +//KT-3822 Compiler crashes when use invoke convention with `this` in class which extends Function0 +// IGNORE_BACKEND: JS, NATIVE +// JS backend does not allow to implement Function{N} interfaces + +class B() : Function0 { + override fun invoke() = true + + fun foo() = this() // Exception +} + +fun box() = if (B().foo()) "OK" else "fail" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt1038.kt b/backend.native/tests/external/codegen/blackbox/functions/kt1038.kt new file mode 100644 index 00000000000..36770408c78 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt1038.kt @@ -0,0 +1,64 @@ +//KT-1038 Cannot compile lazy iterators + +class YieldingIterator(val yieldingFunction : ()->T?) : Iterator +{ + var current : T? = yieldingFunction() + override fun next(): T { + val next = current; + if (next != null) + { + current = yieldingFunction() + return next + } + else throw IndexOutOfBoundsException() + } + override fun hasNext(): Boolean = current != null +} + +class YieldingIterable(val yielderFactory : ()->(()->T?)) : Iterable +{ + override fun iterator(): Iterator = YieldingIterator(yielderFactory()) +} + +public fun Iterable.lazy() : Iterable + { + return YieldingIterable { + val iterator = this.iterator(); + { if (iterator.hasNext()) iterator.next() else null } + } + } + +infix fun Iterable.where(predicate : (TItem)->Boolean) : Iterable + { + return YieldingIterable { + val iterator = this.iterator() + fun yielder() : TItem? { + while(iterator.hasNext()) + { + val next = iterator.next() + if (predicate(next)) + return next + } + return null + } + { yielder() } + } + } + +infix fun Iterable.select(selector : (TItem)->TResult) : Iterable + { + return YieldingIterable { + val iterator = this.iterator(); + { if(iterator.hasNext()) selector(iterator.next()) else null } + } + } + +fun box() : String { + val x = 0..100 + val filtered = x where { it % 2 == 0 } + val xx = x select { it * 2 } + var res = 0 + for (x in xx) + res += x + return if (res == 10100) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt1199.kt b/backend.native/tests/external/codegen/blackbox/functions/kt1199.kt new file mode 100644 index 00000000000..6560f431d58 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt1199.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + + +interface MyIterator { + operator fun hasNext() : Boolean + operator fun next() : T +} + +operator fun T?.iterator() = object : MyIterator { + var hasNext = this@iterator != null + private set + override fun hasNext() = hasNext + + override fun next() : T { + if (hasNext) { + hasNext = false + return this@iterator!! + } + throw java.util.NoSuchElementException() + } +} + +fun box() : String { + var k = 0 + for (i in 1) { + k++ + } + return if(k == 1) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt1413.kt b/backend.native/tests/external/codegen/blackbox/functions/kt1413.kt new file mode 100644 index 00000000000..15b496fb9b9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt1413.kt @@ -0,0 +1,26 @@ +package t + +interface I{ + fun f() +} + +class Test{ + fun foo(){ + val i : I = object : I { + override fun f() { + fun local(){ + bar() + } + local() + } + } + i.f() + } + + fun bar(){} +} + +fun box() : String { + Test().foo() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt1649_1.kt b/backend.native/tests/external/codegen/blackbox/functions/kt1649_1.kt new file mode 100644 index 00000000000..849bf5525ff --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt1649_1.kt @@ -0,0 +1,18 @@ +interface A { + val method : (() -> Unit)? +} + +fun test(a : A) { + if (a.method != null) { + a.method!!() + } +} + +class B : A { + override val method = { } +} + +fun box(): String { + test(B()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt1649_2.kt b/backend.native/tests/external/codegen/blackbox/functions/kt1649_2.kt new file mode 100644 index 00000000000..33f420dc3f9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt1649_2.kt @@ -0,0 +1,18 @@ +interface A { + val method : () -> Unit? +} + +fun test(a : A) { + if (a.method != null) { + a.method!!() + } +} + +class B : A { + override val method = { } +} + +fun box(): String { + test(B()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt1739.kt b/backend.native/tests/external/codegen/blackbox/functions/kt1739.kt new file mode 100644 index 00000000000..a990645b61a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt1739.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +public class RunnableFunctionWrapper(val f : () -> Unit) : Runnable { + public override fun run() { + f() + } +} + +fun box() : String { + var res = "" + RunnableFunctionWrapper({ res = "OK" }).run() + return res +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt2270.kt b/backend.native/tests/external/codegen/blackbox/functions/kt2270.kt new file mode 100644 index 00000000000..27d631e3d2f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt2270.kt @@ -0,0 +1,6 @@ +class A( + val i : Int, + val j : Int = i +) + +fun box() = if (A(1).j == 1) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt2271.kt b/backend.native/tests/external/codegen/blackbox/functions/kt2271.kt new file mode 100644 index 00000000000..efc623a6519 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt2271.kt @@ -0,0 +1,3 @@ +fun foo(i: Int, j: Int = i) = j + +fun box() = if (foo(1) == 1) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt2280.kt b/backend.native/tests/external/codegen/blackbox/functions/kt2280.kt new file mode 100644 index 00000000000..79debb72bdf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt2280.kt @@ -0,0 +1,7 @@ +fun box(): String { + fun rmrf(i: Int) { + if (i > 0) rmrf(i - 1) + } + rmrf(5) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt2481.kt b/backend.native/tests/external/codegen/blackbox/functions/kt2481.kt new file mode 100644 index 00000000000..ea353c41cb1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt2481.kt @@ -0,0 +1,14 @@ +fun box() = + B().method() + +public open class A(){ + public open fun method() : String = "OK" +} + +public class B(): A(){ + public override fun method() : String { + return ({ + super.method() + })() + } +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt2716.kt b/backend.native/tests/external/codegen/blackbox/functions/kt2716.kt new file mode 100644 index 00000000000..0ba57fd380a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt2716.kt @@ -0,0 +1,11 @@ +package someTest + +public class Some private constructor(val v: String) { + companion object { + public fun init(v: String): Some { + return Some(v) + } + } +} + +fun box() = Some.init("OK").v diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt2739.kt b/backend.native/tests/external/codegen/blackbox/functions/kt2739.kt new file mode 100644 index 00000000000..296dd3bc8c3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt2739.kt @@ -0,0 +1,10 @@ +// KT-2739 Error type inferred for hashSet(Pair, Pair, Pair) + +fun foo(vararg ts: T): T? = null + +class Pair(a: A) + +fun box(): String { + val v = foo(Pair(1)) + return if (v == null) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt2929.kt b/backend.native/tests/external/codegen/blackbox/functions/kt2929.kt new file mode 100644 index 00000000000..4367923fc29 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt2929.kt @@ -0,0 +1,7 @@ +fun foo(): Int { + val a = "test" + val b = "test" + return a.compareTo(b) +} + +fun box(): String = if(foo() == 0) "OK" else "Fail" diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt3214.kt b/backend.native/tests/external/codegen/blackbox/functions/kt3214.kt new file mode 100644 index 00000000000..8ff33fcad23 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt3214.kt @@ -0,0 +1,33 @@ +class A { + fun get(vararg x: Int) = x.size +} + +class B { + fun get(vararg x: Unit) = x.size +} + +fun test1(a: A): Int { + return a.get(1) +} + +fun test2(a: A): Int { + return a.get(1, 2) +} + +fun test3(b: B): Int { + return b.get(Unit, Unit) +} + + +fun box() : String { + var result = test1(A()) + if (result != 1) return "fail1: $result" + + result = test2(A()) + if (result != 2) return "fail2: $result" + + result = test3(B()) + if (result != 2) return "fail3: $result" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt3313.kt b/backend.native/tests/external/codegen/blackbox/functions/kt3313.kt new file mode 100644 index 00000000000..5e2e887c2a8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt3313.kt @@ -0,0 +1,7 @@ +fun foo(t: T) { +} + +fun box(): String { + foo(null) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt3573.kt b/backend.native/tests/external/codegen/blackbox/functions/kt3573.kt new file mode 100644 index 00000000000..e97d3620de0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt3573.kt @@ -0,0 +1,12 @@ +class Data + +fun newInit(f: Data.() -> Data) = Data().f() + +class TestClass { + val test: Data = newInit() { this } +} + +fun box() : String { + TestClass() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt3724.kt b/backend.native/tests/external/codegen/blackbox/functions/kt3724.kt new file mode 100644 index 00000000000..e1e5edac345 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt3724.kt @@ -0,0 +1,24 @@ +class Comment() { + var article = "" +} + +fun new(body: Comment.() -> Unit) : Comment { + val c = Comment() + c.body() + return c +} + +open class Request(val handler : Any.() -> Comment) { + val s = handler().article +} + + +class A : Request ({ + new { + this.article = "OK" + } +}) + +fun box() : String { + return A().s +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt395.kt b/backend.native/tests/external/codegen/blackbox/functions/kt395.kt new file mode 100644 index 00000000000..310640226e0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt395.kt @@ -0,0 +1,12 @@ +fun Any.with(operation : Any.() -> Any) = operation().toString() + +val f = { a : Int -> } + +fun box () : String { + return if(20.with { + this + } == "20") + "OK" + else + "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt785.kt b/backend.native/tests/external/codegen/blackbox/functions/kt785.kt new file mode 100644 index 00000000000..e3073856d42 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt785.kt @@ -0,0 +1,13 @@ +class A() { + var x : Int = 0 + + var z = { + x++ + } +} + +fun box() : String { + val a = A() + a.z() //problem is here + return if (a.x == 1) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/kt873.kt b/backend.native/tests/external/codegen/blackbox/functions/kt873.kt new file mode 100644 index 00000000000..21c3dcd3338 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/kt873.kt @@ -0,0 +1,11 @@ +fun box() : String { + val fps : Double = 1.toDouble() + var mspf : Long + { + if ((fps.toInt() == 0)) + mspf = 0 + else + mspf = (((1000.0 / fps)).toLong()) + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/localFunction.kt b/backend.native/tests/external/codegen/blackbox/functions/localFunction.kt new file mode 100644 index 00000000000..b43377b6ab1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localFunction.kt @@ -0,0 +1,46 @@ +fun IntRange.forEach(body : (Int) -> Unit) { + for(i in this) { + body(i) + } +} + +fun box() : String { + var seed = 0 + + fun local(x: Int) { + fun deep() { + seed += x + } + fun deep2(x : Int) { + seed += x + } + fun Int.iter() { + seed += this + } + + deep() + deep2(-x) + x.iter() + seed += x + } + + for(i in 1..5) { + fun Int.iter() { + seed += this + } + + local(i) + (-i).iter() + } + + fun local2(y: Int) { + seed += y + } + + (1..5).forEach { + local2(it) + } + + + return if(seed == 30) "OK" else seed.toString() +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/localFunctions/callInlineLocalInLambda.kt b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/callInlineLocalInLambda.kt new file mode 100644 index 00000000000..a59a7507800 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/callInlineLocalInLambda.kt @@ -0,0 +1,15 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun foo(x: String, block: (String) -> String) = block(x) + +fun box(): String { + fun bar(y: String) = y + "cde" + + val res = foo("abc") { bar(it) } + + assertEquals("abccde", res) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/localFunctions/definedWithinLambda.kt b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/definedWithinLambda.kt new file mode 100644 index 00000000000..935d8b4963c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/definedWithinLambda.kt @@ -0,0 +1,16 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun foo(x: String, block: (String) -> String) = block(x) + +fun box(): String { + val res = foo("abc") { + fun bar(y: String) = y + "cde" + bar(it) + } + + assertEquals("abccde", res) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/localFunctions/definedWithinLambdaInnerUsage1.kt b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/definedWithinLambdaInnerUsage1.kt new file mode 100644 index 00000000000..6609be78133 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/definedWithinLambdaInnerUsage1.kt @@ -0,0 +1,16 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun foo(x: String, block: (String) -> String) = block(x) + +fun box(): String { + val res = foo("abc") { + fun bar(y: String) = y + "cde" + foo(it) { bar(it) } + } + + assertEquals("abccde", res) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/localFunctions/definedWithinLambdaInnerUsage2.kt b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/definedWithinLambdaInnerUsage2.kt new file mode 100644 index 00000000000..158e845f9ad --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/definedWithinLambdaInnerUsage2.kt @@ -0,0 +1,17 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun foo(x: String, block: (String) -> String) = block(x) +fun noInlineFoo(x: String, block: (String) -> String) = block(x) + +fun box(): String { + val res = foo("abc") { + fun bar(y: String) = y + "cde" + noInlineFoo(it) { bar(it) } + } + + assertEquals("abccde", res) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt2895.kt b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt2895.kt new file mode 100644 index 00000000000..76db2bdc71e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt2895.kt @@ -0,0 +1,15 @@ +fun outer() { + fun inner(i: Int) { + if (i > 0){ + { + it: Int -> inner(0) // <- invocation of literal itself is generated instead + }.invoke(1) + } + } + inner(1) +} + +fun box(): String { + outer() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt3308.kt b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt3308.kt new file mode 100644 index 00000000000..b97dfa7fb79 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt3308.kt @@ -0,0 +1,5 @@ +fun box(): String { + fun foo(t: T) = t + + return foo("OK") +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt3978.kt b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt3978.kt new file mode 100644 index 00000000000..03ba97cd9b7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt3978.kt @@ -0,0 +1,10 @@ +fun box() : String { + + + fun local(i: Int = 1) : Int { + return i + } + + return if (local() != 1) "fail" else "OK" +} + diff --git a/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4119.kt b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4119.kt new file mode 100644 index 00000000000..746e41ee392 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4119.kt @@ -0,0 +1,12 @@ +fun foo(f: (Int?) -> Int): Int { + return f(0) +} + +fun box() : String { + infix operator fun Int?.plus(a: Int) : Int = a!! + 2 + + if (foo { it + 1 } != 3) return "Fail 1" + if (foo { it plus 1 } != 3) return "Fail 2" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4119_2.kt b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4119_2.kt new file mode 100644 index 00000000000..edb647f84a9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4119_2.kt @@ -0,0 +1,19 @@ +fun box(): String { + infix fun Int.foo(a: Int): Int = a + 2 + + val s = object { + fun test(): Int { + return 1 foo 1 + } + } + + fun local(): Int { + return 1 foo 1 + } + + if (s.test() != 3) return "Fail" + + if (local() != 3) return "Fail" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4514.kt b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4514.kt new file mode 100644 index 00000000000..c767d3f0352 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4514.kt @@ -0,0 +1,9 @@ +fun box(): String { + fun String.f() = this + val vf: String.() -> String = { this } + + val localExt = "O".f() + "K"?.f() + if (localExt != "OK") return "localExt $localExt" + + return "O".vf() + "K"?.vf() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4777.kt b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4777.kt new file mode 100644 index 00000000000..27e83c06c12 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4777.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +var result = "Fail" + +val p = object : Runnable { + override fun run() { + fun T.id() = this + + result = "OK".id() + } +} + +fun box(): String { + p.run() + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4783.kt b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4783.kt new file mode 100644 index 00000000000..5d5d9d55f6a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4783.kt @@ -0,0 +1,18 @@ +class T(val value: Int) { +} + +fun local() : Int { + + operator fun T.get(s: Int): Int { + return s * this.value + } + + var t = T(11) + return t[2] +} + +fun box() : String { + if (local() != 22) return "fail1 ${local()} " + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4784.kt b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4784.kt new file mode 100644 index 00000000000..404fce279be --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4784.kt @@ -0,0 +1,20 @@ +open class T(var value: Int) {} + +fun plusAssign(): T { + + operator fun T.plusAssign(s: Int) { + value += s + } + + var t = T(1) + t += 1 + + return t +} + +fun box(): String { + val result = plusAssign().value + if (result != 2) return "fail 1: $result" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4989.kt b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4989.kt new file mode 100644 index 00000000000..87767469738 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/kt4989.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class It(val id: String) + +fun box(): String { + val projectId = "projectId" + val it = It("it") + + + fun selectMetaRunnerId(): String { + operator fun Int?.inc() = (this ?: 0) + 1 + var counter: Int? = null + fun path(metaRunnerId: String) = counter != 2 + + var i = 0 + while (true) { + val name = projectId + "_" + it.id + (if (counter == null) "" else "_$counter") + if (!path(name)) { + return name + } + counter++ + + i++ + if (i > 2) return "Infinity loop: $counter" + } + } + val X = selectMetaRunnerId() + if (X != projectId + "_" + it.id + "_2") return "fail: $X" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/localFunctions/localExtensionOnNullableParameter.kt b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/localExtensionOnNullableParameter.kt new file mode 100644 index 00000000000..709b1c9ac1e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/localExtensionOnNullableParameter.kt @@ -0,0 +1,21 @@ +open class T(var value: Int) {} + +fun localExtensionOnNullableParameter(): T { + + fun T.local(s: Int) { + value += s + } + + var t: T? = T(1) + t?.local(2) + + return t!! +} + + +fun box(): String { + val result = localExtensionOnNullableParameter().value + if (result != 3) return "fail 2: $result" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/localFunctions/localFunctionInConstructor.kt b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/localFunctionInConstructor.kt new file mode 100644 index 00000000000..5f294911561 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localFunctions/localFunctionInConstructor.kt @@ -0,0 +1,15 @@ +class Test { + + val property:Int + init { + fun local():Int { + return 10; + } + property = local(); + } + +} + +fun box(): String { + return if (Test().property == 10) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/localReturnInsideFunctionExpression.kt b/backend.native/tests/external/codegen/blackbox/functions/localReturnInsideFunctionExpression.kt new file mode 100644 index 00000000000..5d3a5ad1a33 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/localReturnInsideFunctionExpression.kt @@ -0,0 +1,10 @@ +fun simple() = fun (): Boolean { return true } + +fun withLabel() = l@ fun (): Boolean { return@l true } + +fun box(): String { + if (!simple()()) return "Test simple failed" + if (!withLabel()()) return "Test withLabel failed" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/nothisnoclosure.kt b/backend.native/tests/external/codegen/blackbox/functions/nothisnoclosure.kt new file mode 100644 index 00000000000..68369ae57eb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/nothisnoclosure.kt @@ -0,0 +1,16 @@ +fun foo(x: Int) {} + +fun loop(times : Int) { + var left = times + while(left > 0) { + val u : (value : Int) -> Unit = { + foo(it) + } + u(left--) + } +} + +fun box() : String { + loop(5) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/functions/prefixRecursiveCall.kt b/backend.native/tests/external/codegen/blackbox/functions/prefixRecursiveCall.kt new file mode 100644 index 00000000000..7fe750fc4ec --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/prefixRecursiveCall.kt @@ -0,0 +1,8 @@ +operator fun String.unaryPlus() : String { + if (this == "") { + return "done" + } + return +"" +} + +fun box() : String = if (+"11" == "done") "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/recursiveCompareTo.kt b/backend.native/tests/external/codegen/blackbox/functions/recursiveCompareTo.kt new file mode 100644 index 00000000000..aeafd27f6e0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/recursiveCompareTo.kt @@ -0,0 +1,11 @@ +class C + +operator fun C.compareTo(o: C) : Int { + if (this == o) return 0 + if (o >= o) { + return 1 + } + return -1 +} + +fun box() : String = if (C() > C()) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/functions/recursiveIncrementCall.kt b/backend.native/tests/external/codegen/blackbox/functions/recursiveIncrementCall.kt new file mode 100644 index 00000000000..b5985d5606c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/functions/recursiveIncrementCall.kt @@ -0,0 +1,12 @@ +operator fun String.inc() : String { + if (this == "") { + return "done" + } + var s = "" + return ++s +} + +fun box() : String { + var s = "11test" + return if (++s == "done") "OK" else "FAIL" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/hashPMap/empty.kt b/backend.native/tests/external/codegen/blackbox/hashPMap/empty.kt new file mode 100644 index 00000000000..a7061b676d1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/hashPMap/empty.kt @@ -0,0 +1,27 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.internal.pcollections.HashPMap +import kotlin.test.* + +fun box(): String { + val map = HashPMap.empty()!! + + assertEquals(0, map.size()) + + assertFalse(map.containsKey("")) + assertFalse(map.containsKey("abacaba")) + assertEquals(null, map[""]) + assertEquals(null, map["lol"]) + + // Check that doesn't create a new map + assertEquals(map, map.minus("")) + + // Check that all empty()s are equal + val other = HashPMap.empty()!! + assertEquals(map, other) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/hashPMap/manyNumbers.kt b/backend.native/tests/external/codegen/blackbox/hashPMap/manyNumbers.kt new file mode 100644 index 00000000000..21efec77fa0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/hashPMap/manyNumbers.kt @@ -0,0 +1,52 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import java.util.* +import kotlin.reflect.jvm.internal.pcollections.HashPMap +import kotlin.test.* + +fun digitSum(number: Int): Int { + var x = number + var ans = 0 + while (x != 0) { + ans += x % 10 + x /= 10 + } + return ans +} + +val N = 1000000 + +fun box(): String { + var map = HashPMap.empty()!! + + for (x in 1..N) { + map = map.plus(x, digitSum(x))!! + } + + assertEquals(N, map.size()) + + // Check in reverse order just in case + for (x in N downTo 1) { + assertTrue(map.containsKey(x), "Not found: $x") + assertEquals(digitSum(x), map[x], "Incorrect value for $x") + } + + // Delete in random order + val list = (1..N).toCollection(ArrayList()) + Collections.shuffle(list, Random(42)) + for (x in list) { + map = map.minus(x)!! + } + + assertEquals(0, map.size()) + + for (x in 1..N) { + assertFalse(map.containsKey(x), "Incorrectly found: $x") + assertEquals(null, map[x], "Incorrectly found value for $x") + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/hashPMap/rewriteWithDifferent.kt b/backend.native/tests/external/codegen/blackbox/hashPMap/rewriteWithDifferent.kt new file mode 100644 index 00000000000..741a3024365 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/hashPMap/rewriteWithDifferent.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.internal.pcollections.HashPMap +import kotlin.test.* + +fun box(): String { + var map = HashPMap.empty()!! + + map = map.plus("lol", 42)!! + map = map.plus("lol", 239)!! + + assertEquals(1, map.size()) + assertTrue(map.containsKey("lol")) + assertFalse(map.containsKey("")) + assertEquals(239, map["lol"]) + assertEquals(null, map[""]) + + map = map.plus("", 0)!! + map = map.plus("", 2.71828)!! + map = map.plus("lol", 42)!! + map = map.plus("", 3.14)!! + + assertEquals(2, map.size()) + assertTrue(map.containsKey("lol")) + assertTrue(map.containsKey("")) + assertEquals(42, map["lol"]) + assertEquals(3.14, map[""]) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/hashPMap/rewriteWithEqual.kt b/backend.native/tests/external/codegen/blackbox/hashPMap/rewriteWithEqual.kt new file mode 100644 index 00000000000..eb3642c5422 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/hashPMap/rewriteWithEqual.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.internal.pcollections.HashPMap +import kotlin.test.* + +fun box(): String { + var map = HashPMap.empty()!! + + map = map.plus("lol", 42)!! + map = map.plus("lol", 42)!! + + assertEquals(1, map.size()) + assertTrue(map.containsKey("lol")) + assertFalse(map.containsKey("")) + assertEquals(42, map["lol"]) + assertEquals(null, map[""]) + + map = map.plus("", 0)!! + map = map.plus("", 0)!! + map = map.plus("lol", 42)!! + map = map.plus("", 0)!! + + assertEquals(2, map.size()) + assertTrue(map.containsKey("lol")) + assertTrue(map.containsKey("")) + assertEquals(42, map["lol"]) + assertEquals(0, map[""]) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/hashPMap/simplePlusGet.kt b/backend.native/tests/external/codegen/blackbox/hashPMap/simplePlusGet.kt new file mode 100644 index 00000000000..81a2aaceb34 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/hashPMap/simplePlusGet.kt @@ -0,0 +1,29 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.internal.pcollections.HashPMap +import kotlin.test.* + +fun box(): String { + var map = HashPMap.empty()!! + + map = map.plus("lol", 42)!! + + assertEquals(1, map.size()) + assertTrue(map.containsKey("lol")) + assertFalse(map.containsKey("")) + assertEquals(42, map["lol"]) + assertEquals(null, map[""]) + + map = map.plus("", 0)!! + + assertEquals(2, map.size()) + assertTrue(map.containsKey("lol")) + assertTrue(map.containsKey("")) + assertEquals(42, map["lol"]) + assertEquals(0, map[""]) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/hashPMap/simplePlusMinus.kt b/backend.native/tests/external/codegen/blackbox/hashPMap/simplePlusMinus.kt new file mode 100644 index 00000000000..2830c5d3122 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/hashPMap/simplePlusMinus.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.internal.pcollections.HashPMap +import kotlin.test.* + +fun box(): String { + var map = HashPMap.empty()!! + + map = map.plus("lol", 42)!! + map = map.minus("lol")!! + + assertEquals(0, map.size()) + assertFalse(map.containsKey("lol")) + assertEquals(null, map["lol"]) + + map = map.plus("abc", "a")!! + map = map.minus("abc")!! + map = map.plus("abc", "d")!! + + assertEquals(1, map.size()) + assertTrue(map.containsKey("abc")) + assertEquals("d", map["abc"]) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/anyToReal.kt b/backend.native/tests/external/codegen/blackbox/ieee754/anyToReal.kt new file mode 100644 index 00000000000..3ba490d870e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/anyToReal.kt @@ -0,0 +1,15 @@ +fun box(): String { + val plusZero: Any = 0.0 + val minusZero: Any = -0.0 + if ((minusZero as Double) < (plusZero as Double)) return "fail 0" + + val plusZeroF: Any = 0.0F + val minusZeroF: Any = -0.0F + if ((minusZeroF as Float) < (plusZeroF as Float)) return "fail 1" + + if ((minusZero as Double) != (plusZero as Double)) return "fail 3" + + if ((minusZeroF as Float) != (plusZeroF as Float)) return "fail 4" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/comparableTypeCast.kt b/backend.native/tests/external/codegen/blackbox/ieee754/comparableTypeCast.kt new file mode 100644 index 00000000000..4f941c7fcb6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/comparableTypeCast.kt @@ -0,0 +1,14 @@ +// IGNORE_BACKEND: JS, NATIVE +fun box(): String { + if ((-0.0 as Comparable) >= 0.0) return "fail 0" + if ((-0.0F as Comparable) >= 0.0F) return "fail 1" + + + if ((-0.0 as Comparable) == 0.0) return "fail 3" + if (-0.0 == (0.0 as Comparable)) return "fail 4" + + if ((-0.0F as Comparable) == 0.0F) return "fail 5" + if (-0.0F == (0.0F as Comparable)) return "fail 6" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/dataClass.kt b/backend.native/tests/external/codegen/blackbox/ieee754/dataClass.kt new file mode 100644 index 00000000000..d4b647a1522 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/dataClass.kt @@ -0,0 +1,9 @@ +// IGNORE_BACKEND: JS, NATIVE +data class Test(val z1: Double, val z2: Double?) + +fun box(): String { + val x = Test(Double.NaN, Double.NaN) + val y = Test(Double.NaN, Double.NaN) + + return if (x == y) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/equalsDouble.kt b/backend.native/tests/external/codegen/blackbox/ieee754/equalsDouble.kt new file mode 100644 index 00000000000..28d5c90e7f6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/equalsDouble.kt @@ -0,0 +1,22 @@ +fun equals1(a: Double, b: Double) = a == b + +fun equals2(a: Double?, b: Double?) = a!! == b!! + +fun equals3(a: Double?, b: Double?) = a != null && b != null && a == b + +fun equals4(a: Double?, b: Double?) = if (a is Double && b is Double) a == b else null!! + +fun equals5(a: Any?, b: Any?) = if (a is Double && b is Double) a == b else null!! + + +fun box(): String { + if (-0.0 != 0.0) return "fail 0" + if (!equals1(-0.0, 0.0)) return "fail 1" + if (!equals2(-0.0, 0.0)) return "fail 2" + if (!equals3(-0.0, 0.0)) return "fail 3" + if (!equals4(-0.0, 0.0)) return "fail 4" + if (!equals5(-0.0, 0.0)) return "fail 5" + + return "OK" +} + diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/equalsFloat.kt b/backend.native/tests/external/codegen/blackbox/ieee754/equalsFloat.kt new file mode 100644 index 00000000000..26187f688d0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/equalsFloat.kt @@ -0,0 +1,22 @@ +fun equals1(a: Float, b: Float) = a == b + +fun equals2(a: Float?, b: Float?) = a!! == b!! + +fun equals3(a: Float?, b: Float?) = a != null && b != null && a == b + +fun equals4(a: Float?, b: Float?) = if (a is Float && b is Float) a == b else null!! + +fun equals5(a: Any?, b: Any?) = if (a is Float && b is Float) a == b else null!! + + +fun box(): String { + if (-0.0F != 0.0F) return "fail 0" + if (!equals1(-0.0F, 0.0F)) return "fail 1" + if (!equals2(-0.0F, 0.0F)) return "fail 2" + if (!equals3(-0.0F, 0.0F)) return "fail 3" + if (!equals4(-0.0F, 0.0F)) return "fail 4" + if (!equals5(-0.0F, 0.0F)) return "fail 5" + + return "OK" +} + diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/equalsNullableDouble.kt b/backend.native/tests/external/codegen/blackbox/ieee754/equalsNullableDouble.kt new file mode 100644 index 00000000000..229629cb1e5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/equalsNullableDouble.kt @@ -0,0 +1,30 @@ +fun equals1(a: Double, b: Double?) = a == b + +fun equals2(a: Double?, b: Double?) = a!! == b!! + +fun equals3(a: Double?, b: Double?) = a != null && a == b + +fun equals4(a: Double?, b: Double?) = if (a is Double) a == b else null!! + +fun equals5(a: Any?, b: Any?) = if (a is Double && b is Double?) a == b else null!! + +fun equals6(a: Any?, b: Any?) = if (a is Double? && b is Double) a == b else null!! + +fun equals7(a: Double?, b: Double?) = a == b + +fun equals8(a: Any?, b: Any?) = if (a is Double? && b is Double?) a == b else null!! + + +fun box(): String { + if (!equals1(-0.0, 0.0)) return "fail 1" + if (!equals2(-0.0, 0.0)) return "fail 2" + if (!equals3(-0.0, 0.0)) return "fail 3" + if (!equals4(-0.0, 0.0)) return "fail 4" + if (!equals5(-0.0, 0.0)) return "fail 5" + if (!equals6(-0.0, 0.0)) return "fail 6" + if (!equals7(-0.0, 0.0)) return "fail 7" + if (!equals8(-0.0, 0.0)) return "fail 8" + + return "OK" +} + diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/explicitCompareCall.kt b/backend.native/tests/external/codegen/blackbox/ieee754/explicitCompareCall.kt new file mode 100644 index 00000000000..cfb9877257a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/explicitCompareCall.kt @@ -0,0 +1,20 @@ +// IGNORE_BACKEND: JS, NATIVE +fun less1(a: Double, b: Double) = a.compareTo(b) == -1 + +fun less2(a: Double?, b: Double?) = a!!.compareTo(b!!) == -1 + +fun less3(a: Double?, b: Double?) = a != null && b != null && a.compareTo(b) == -1 + +fun less4(a: Double?, b: Double?) = if (a is Double && b is Double) a.compareTo(b) == -1 else null!! + +fun less5(a: Any?, b: Any?) = if (a is Double && b is Double) a.compareTo(b) == -1 else null!! + +fun box(): String { + if (!less1(-0.0, 0.0)) return "fail 1" + if (!less2(-0.0, 0.0)) return "fail 2" + if (!less3(-0.0, 0.0)) return "fail 3" + if (!less4(-0.0, 0.0)) return "fail 4" + if (!less5(-0.0, 0.0)) return "fail 5" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/explicitEqualsCall.kt b/backend.native/tests/external/codegen/blackbox/ieee754/explicitEqualsCall.kt new file mode 100644 index 00000000000..d9003f38af2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/explicitEqualsCall.kt @@ -0,0 +1,21 @@ +// IGNORE_BACKEND: JS, NATIVE + +fun equals1(a: Double, b: Double) = a.equals(b) + +fun equals2(a: Double?, b: Double?) = a!!.equals(b!!) + +fun equals3(a: Double?, b: Double?) = a != null && b != null && a.equals(b) + +fun equals4(a: Double?, b: Double?) = if (a is Double && b is Double) a.equals(b) else null!! + + +fun box(): String { + if ((-0.0).equals(0.0)) return "fail 0" + if (equals1(-0.0, 0.0)) return "fail 1" + if (equals2(-0.0, 0.0)) return "fail 2" + if (equals3(-0.0, 0.0)) return "fail 3" + if (equals4(-0.0, 0.0)) return "fail 4" + + return "OK" +} + diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/generic.kt b/backend.native/tests/external/codegen/blackbox/ieee754/generic.kt new file mode 100644 index 00000000000..6d621ffd2c0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/generic.kt @@ -0,0 +1,18 @@ +// FILE: b.kt + +class Foo(val minus0: T, val plus0: T) { + +} + +fun box(): String { + val foo = Foo(-0.0, 0.0) + val fooF = Foo(-0.0F, 0.0F) + + if (foo.minus0 < foo.plus0) return "fail 0" + if (fooF.minus0 < fooF.plus0) return "fail 1" + + if (foo.minus0 != foo.plus0) return "fail 3" + if (fooF.minus0 != fooF.plus0) return "fail 4" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/greaterDouble.kt b/backend.native/tests/external/codegen/blackbox/ieee754/greaterDouble.kt new file mode 100644 index 00000000000..2359ca5d077 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/greaterDouble.kt @@ -0,0 +1,20 @@ +fun greater1(a: Double, b: Double) = a > b + +fun greater2(a: Double?, b: Double?) = a!! > b!! + +fun greater3(a: Double?, b: Double?) = a != null && b != null && a > b + +fun greater4(a: Double?, b: Double?) = if (a is Double && b is Double) a > b else null!! + +fun greater5(a: Any?, b: Any?) = if (a is Double && b is Double) a > b else null!! + +fun box(): String { + if (0.0 > -0.0) return "fail 0" + if (greater1(0.0, -0.0)) return "fail 1" + if (greater2(0.0, -0.0)) return "fail 2" + if (greater3(0.0, -0.0)) return "fail 3" + if (greater4(0.0, -0.0)) return "fail 4" + if (greater5(0.0, -0.0)) return "fail 5" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/greaterFloat.kt b/backend.native/tests/external/codegen/blackbox/ieee754/greaterFloat.kt new file mode 100644 index 00000000000..ebcf4ef7147 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/greaterFloat.kt @@ -0,0 +1,20 @@ +fun greater1(a: Float, b: Float) = a > b + +fun greater2(a: Float?, b: Float?) = a!! > b!! + +fun greater3(a: Float?, b: Float?) = a != null && b != null && a > b + +fun greater4(a: Float?, b: Float?) = if (a is Float && b is Float) a > b else null!! + +fun greater5(a: Any?, b: Any?) = if (a is Float && b is Float) a > b else null!! + +fun box(): String { + if (0.0F > -0.0F) return "fail 0" + if (greater1(0.0F, -0.0F)) return "fail 1" + if (greater2(0.0F, -0.0F)) return "fail 2" + if (greater3(0.0F, -0.0F)) return "fail 3" + if (greater4(0.0F, -0.0F)) return "fail 4" + if (greater5(0.0F, -0.0F)) return "fail 5" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/inline.kt b/backend.native/tests/external/codegen/blackbox/ieee754/inline.kt new file mode 100644 index 00000000000..8238f6242ac --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/inline.kt @@ -0,0 +1,49 @@ +// IGNORE_BACKEND: JS, NATIVE + +inline fun less(a: Comparable, b: Double): Boolean { + return a < b +} + +inline fun equals(a: Comparable, b: Comparable): Boolean { + return a == b +} + +inline fun > lessGeneric(a: T, b: Double): Boolean { + return a < b +} + +inline fun > equalsGeneric(a: T, b: Double): Boolean { + return a == b +} + +inline fun > lessReified(a: T, b: Double): Boolean { + return a < b +} + +inline fun > equalsReified(a: T, b: T): Boolean { + return a == b +} + +inline fun less754(a: Double, b: Double): Boolean { + return a < b +} + +inline fun equals754(a: Double, b: Double): Boolean { + return a == b +} + +fun box(): String { + if (!less(-0.0, 0.0)) return "fail 1" + if (equals(-0.0, 0.0)) return "fail 2" + + if (!lessGeneric(-0.0, 0.0)) return "fail 3" + if (equalsGeneric(-0.0, 0.0)) return "fail 4" + + if (!lessReified(-0.0, 0.0)) return "fail 5" + if (equalsReified(-0.0, 0.0)) return "fail 6" + + if (less754(-0.0, 0.0)) return "fail 7" + if (!equals754(-0.0, 0.0)) return "fail 8" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/lessDouble.kt b/backend.native/tests/external/codegen/blackbox/ieee754/lessDouble.kt new file mode 100644 index 00000000000..b25363bdb65 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/lessDouble.kt @@ -0,0 +1,20 @@ +fun less1(a: Double, b: Double) = a < b + +fun less2(a: Double?, b: Double?) = a!! < b!! + +fun less3(a: Double?, b: Double?) = a != null && b != null && a < b + +fun less4(a: Double?, b: Double?) = if (a is Double && b is Double) a < b else null!! + +fun less5(a: Any?, b: Any?) = if (a is Double && b is Double) a < b else null!! + +fun box(): String { + if (-0.0 < 0.0) return "fail 0" + if (less1(-0.0, 0.0)) return "fail 1" + if (less2(-0.0, 0.0)) return "fail 2" + if (less3(-0.0, 0.0)) return "fail 3" + if (less4(-0.0, 0.0)) return "fail 4" + if (less5(-0.0, 0.0)) return "fail 5" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/lessFloat.kt b/backend.native/tests/external/codegen/blackbox/ieee754/lessFloat.kt new file mode 100644 index 00000000000..efea2decef4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/lessFloat.kt @@ -0,0 +1,20 @@ +fun less1(a: Float, b: Float) = a < b + +fun less2(a: Float?, b: Float?) = a!! < b!! + +fun less3(a: Float?, b: Float?) = a != null && b != null && a < b + +fun less4(a: Float?, b: Float?) = if (a is Float && b is Float) a < b else true + +fun less5(a: Any?, b: Any?) = if (a is Float && b is Float) a < b else true + +fun box(): String { + if (-0.0F < 0.0F) return "fail 0" + if (less1(-0.0F, 0.0F)) return "fail 1" + if (less2(-0.0F, 0.0F)) return "fail 2" + if (less3(-0.0F, 0.0F)) return "fail 3" + if (less4(-0.0F, 0.0F)) return "fail 4" + if (less5(-0.0F, 0.0F)) return "fail 5" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/nullableAnyToReal.kt b/backend.native/tests/external/codegen/blackbox/ieee754/nullableAnyToReal.kt new file mode 100644 index 00000000000..7c4a950202f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/nullableAnyToReal.kt @@ -0,0 +1,15 @@ +fun box(): String { + val plusZero: Any? = 0.0 + val minusZero: Any? = -0.0 + if ((minusZero as Double) < (plusZero as Double)) return "fail 0" + + val plusZeroF: Any? = 0.0F + val minusZeroF: Any? = -0.0F + if ((minusZeroF as Float) < (plusZeroF as Float)) return "fail 1" + + if ((minusZero as Double) != (plusZero as Double)) return "fail 3" + + if ((minusZeroF as Float) != (plusZeroF as Float)) return "fail 4" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/safeCall.kt b/backend.native/tests/external/codegen/blackbox/ieee754/safeCall.kt new file mode 100644 index 00000000000..4c30f69761b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/safeCall.kt @@ -0,0 +1,14 @@ +// IGNORE_BACKEND: JS, NATIVE +fun box(): String { + val plusZero: Double? = 0.0 + val minusZero: Double = -0.0 + if (plusZero?.equals(minusZero) ?: null!!) { + return "fail 1" + } + + if (plusZero?.compareTo(minusZero) ?: null!! != 1) { + return "fail 2" + } + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/smartCastToDifferentTypes.kt b/backend.native/tests/external/codegen/blackbox/ieee754/smartCastToDifferentTypes.kt new file mode 100644 index 00000000000..98b087e66e0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/smartCastToDifferentTypes.kt @@ -0,0 +1,14 @@ +// IGNORE_BACKEND: JS, NATIVE +fun box(): String { + val zero: Any = 0.0 + val floatZero: Any = -0.0F + if (zero is Double && floatZero is Float) { + if (zero == floatZero) return "fail 1" + + if (zero <= floatZero) return "fail 2" + + return "OK" + } + + return "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/when.kt b/backend.native/tests/external/codegen/blackbox/ieee754/when.kt new file mode 100644 index 00000000000..c57947e17bf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/when.kt @@ -0,0 +1,21 @@ +fun box(): String { + val plusZero: Any = 0.0 + val minusZero: Any = -0.0 + if (plusZero is Double) { + when (plusZero) { + -0.0 -> { + } + else -> return "fail 1" + } + + if (minusZero is Double) { + when (plusZero) { + minusZero -> { + } + else -> return "fail 2" + } + } + } + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ieee754/whenNoSubject.kt b/backend.native/tests/external/codegen/blackbox/ieee754/whenNoSubject.kt new file mode 100644 index 00000000000..308c9a24cfe --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ieee754/whenNoSubject.kt @@ -0,0 +1,26 @@ +fun box(): String { + val plusZero: Any = 0.0 + val minusZero: Any = -0.0 + if (plusZero is Double && minusZero is Double) { + when { + plusZero < minusZero -> { + return "fail 1" + } + + plusZero > minusZero -> { + return "fail 2" + } + else -> { + } + } + + + when { + plusZero == minusZero -> { + } + else -> return "fail 3" + } + } + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/increment/arrayElement.kt b/backend.native/tests/external/codegen/blackbox/increment/arrayElement.kt new file mode 100644 index 00000000000..e74d4d23515 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/arrayElement.kt @@ -0,0 +1,69 @@ +fun box(): String { + val aByte: Array = arrayOf(1) + val bByte: ByteArray = byteArrayOf(1) + + val aShort: Array = arrayOf(1) + val bShort: ShortArray = shortArrayOf(1) + + val aInt: Array = arrayOf(1) + val bInt: IntArray = intArrayOf(1) + + val aLong: Array = arrayOf(1) + val bLong: LongArray = longArrayOf(1) + + val aFloat: Array = arrayOf(1.0f) + val bFloat: FloatArray = floatArrayOf(1.0f) + + val aDouble: Array = arrayOf(1.0) + val bDouble: DoubleArray = doubleArrayOf(1.0) + + aByte[0]-- + bByte[0]-- + if (aByte[0] != bByte[0]) return "Failed post-decrement Byte: ${aByte[0]} != ${bByte[0]}" + + aByte[0]++ + bByte[0]++ + if (aByte[0] != bByte[0]) return "Failed post-increment Byte: ${aByte[0]} != ${bByte[0]}" + + aShort[0]-- + bShort[0]-- + if (aShort[0] != bShort[0]) return "Failed post-decrement Short: ${aShort[0]} != ${bShort[0]}" + + aShort[0]++ + bShort[0]++ + if (aShort[0] != bShort[0]) return "Failed post-increment Short: ${aShort[0]} != ${bShort[0]}" + + aInt[0]-- + bInt[0]-- + if (aInt[0] != bInt[0]) return "Failed post-decrement Int: ${aInt[0]} != ${bInt[0]}" + + aInt[0]++ + bInt[0]++ + if (aInt[0] != bInt[0]) return "Failed post-increment Int: ${aInt[0]} != ${bInt[0]}" + + aLong[0]-- + bLong[0]-- + if (aLong[0] != bLong[0]) return "Failed post-decrement Long: ${aLong[0]} != ${bLong[0]}" + + aLong[0]++ + bLong[0]++ + if (aLong[0] != bLong[0]) return "Failed post-increment Long: ${aLong[0]} != ${bLong[0]}" + + aFloat[0]++ + bFloat[0]++ + if (aFloat[0] != bFloat[0]) return "Failed post-increment Float: ${aFloat[0]} != ${bFloat[0]}" + + aFloat[0]-- + bFloat[0]-- + if (aFloat[0] != bFloat[0]) return "Failed post-decrement Float: ${aFloat[0]} != ${bFloat[0]}" + + aDouble[0]++ + bDouble[0]++ + if (aDouble[0] != bDouble[0]) return "Failed post-increment Double: ${aDouble[0]} != ${bDouble[0]}" + + aDouble[0]-- + bDouble[0]-- + if (aDouble[0] != bDouble[0]) return "Failed post-decrement Double: ${aDouble[0]} != ${bDouble[0]}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/increment/assignPlusOnSmartCast.kt b/backend.native/tests/external/codegen/blackbox/increment/assignPlusOnSmartCast.kt new file mode 100644 index 00000000000..f3b84e034bd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/assignPlusOnSmartCast.kt @@ -0,0 +1,8 @@ +public fun box() : String { + var i : Int? + i = 10 + // assignPlus on a smart cast should work + i += 1 + + return if (11 == i) "OK" else "fail i = $i" +} diff --git a/backend.native/tests/external/codegen/blackbox/increment/augmentedAssignmentWithComplexRhs.kt b/backend.native/tests/external/codegen/blackbox/increment/augmentedAssignmentWithComplexRhs.kt new file mode 100644 index 00000000000..cc9dccf660b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/augmentedAssignmentWithComplexRhs.kt @@ -0,0 +1,35 @@ +// WITH_RUNTIME +import kotlin.test.* + +var log = "" +var result = 20 +var doubleResult = 40.0 + +fun id(value: T) = value + +fun box(): String { + result += if (id("true") == "true") { + result += 10 + log += "true chosen;" + 3 + } + else { + 4 + } + + assertEquals(23, result) + + doubleResult += if (id("true") == "true") { + doubleResult += 100 + log += "true chosen;" + 2 + } + else { + 5 + } + + assertEquals(42, (doubleResult + 0.1).toInt()) + assertEquals("true chosen;true chosen;", log) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/increment/classNaryGetSet.kt b/backend.native/tests/external/codegen/blackbox/increment/classNaryGetSet.kt new file mode 100644 index 00000000000..121ace263e0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/classNaryGetSet.kt @@ -0,0 +1,15 @@ +object A { + var x = 0 + + operator fun get(i1: Int, i2: Int, i3: Int): Int = x + + operator fun set(i1: Int, i2: Int, i3: Int, value: Int) { + x = value + } +} + +fun box(): String { + A.x = 0 + val xx = A[1, 2, 3]++ + return if (xx != 0 || A.x != 1) "Failed" else "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/increment/classWithGetSet.kt b/backend.native/tests/external/codegen/blackbox/increment/classWithGetSet.kt new file mode 100644 index 00000000000..97d2925acb4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/classWithGetSet.kt @@ -0,0 +1,117 @@ +class AByte(var value: Byte) { + operator fun get(i: Int) = value + + operator fun set(i: Int, newValue: Byte) { + value = newValue + } +} + +class AShort(var value: Short) { + operator fun get(i: Int) = value + + operator fun set(i: Int, newValue: Short) { + value = newValue + } +} + +class AInt(var value: Int) { + operator fun get(i: Int) = value + + operator fun set(i: Int, newValue: Int) { + value = newValue + } +} + +class ALong(var value: Long) { + operator fun get(i: Int) = value + + operator fun set(i: Int, newValue: Long) { + value = newValue + } +} + +class AFloat(var value: Float) { + operator fun get(i: Int) = value + + operator fun set(i: Int, newValue: Float) { + value = newValue + } +} + +class ADouble(var value: Double) { + operator fun get(i: Int) = value + + operator fun set(i: Int, newValue: Double) { + value = newValue + } +} + +fun box(): String { + val aByte = AByte(1) + var bByte: Byte = 1 + + val aShort = AShort(1) + var bShort: Short = 1 + + val aInt = AInt(1) + var bInt: Int = 1 + + val aLong = ALong(1) + var bLong: Long = 1 + + val aFloat = AFloat(1.0f) + var bFloat: Float = 1.0f + + val aDouble = ADouble(1.0) + var bDouble: Double = 1.0 + + aByte[0]++ + bByte++ + if (aByte[0] != bByte) return "Failed post-increment Byte: ${aByte[0]} != $bByte" + + aByte[0]-- + bByte-- + if (aByte[0] != bByte) return "Failed post-decrement Byte: ${aByte[0]} != $bByte" + + aShort[0]++ + bShort++ + if (aShort[0] != bShort) return "Failed post-increment Short: ${aShort[0]} != $bShort" + + aShort[0]-- + bShort-- + if (aShort[0] != bShort) return "Failed post-decrement Short: ${aShort[0]} != $bShort" + + aInt[0]++ + bInt++ + if (aInt[0] != bInt) return "Failed post-increment Int: ${aInt[0]} != $bInt" + + aInt[0]-- + bInt-- + if (aInt[0] != bInt) return "Failed post-decrement Int: ${aInt[0]} != $bInt" + + aLong[0]++ + bLong++ + if (aLong[0] != bLong) return "Failed post-increment Long: ${aLong[0]} != $bLong" + + aLong[0]-- + bLong-- + if (aLong[0] != bLong) return "Failed post-decrement Long: ${aLong[0]} != $bLong" + + aFloat[0]++ + bFloat++ + if (aFloat[0] != bFloat) return "Failed post-increment Float: ${aFloat[0]} != $bFloat" + + aFloat[0]-- + bFloat-- + if (aFloat[0] != bFloat) return "Failed post-decrement Float: ${aFloat[0]} != $bFloat" + + aDouble[0]++ + bDouble++ + if (aDouble[0] != bDouble) return "Failed post-increment Double: ${aDouble[0]} != $bDouble" + + aDouble[0]-- + bDouble-- + if (aDouble[0] != bDouble) return "Failed post-decrement Double: ${aDouble[0]} != $bDouble" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/increment/extOnLong.kt b/backend.native/tests/external/codegen/blackbox/increment/extOnLong.kt new file mode 100644 index 00000000000..9dce4e9da95 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/extOnLong.kt @@ -0,0 +1,8 @@ +operator fun Long.get(i: Int) = this +operator fun Long.set(i: Int, newValue: Long) {} + +fun box(): String { + var x = 0L + val y = x[0]++ + return if (y == 0L) "OK" else "Failed, y=$y" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/increment/genericClassWithGetSet.kt b/backend.native/tests/external/codegen/blackbox/increment/genericClassWithGetSet.kt new file mode 100644 index 00000000000..04825a34f6c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/genericClassWithGetSet.kt @@ -0,0 +1,77 @@ +class A(var value: T) { + operator fun get(i: Int) = value + + operator fun set(i: Int, newValue: T) { + value = newValue + } +} + +fun box(): String { + val aByte = A(1) + var bByte: Byte = 1 + + val aShort = A(1) + var bShort: Short = 1 + + val aInt = A(1) + var bInt: Int = 1 + + val aLong = A(1) + var bLong: Long = 1 + + val aFloat = A(1.0f) + var bFloat: Float = 1.0f + + val aDouble = A(1.0) + var bDouble: Double = 1.0 + + aByte[0]++ + bByte++ + if (aByte[0] != bByte) return "Failed post-increment Byte: ${aByte[0]} != $bByte" + + aByte[0]-- + bByte-- + if (aByte[0] != bByte) return "Failed post-decrement Byte: ${aByte[0]} != $bByte" + + aShort[0]++ + bShort++ + if (aShort[0] != bShort) return "Failed post-increment Short: ${aShort[0]} != $bShort" + + aShort[0]-- + bShort-- + if (aShort[0] != bShort) return "Failed post-decrement Short: ${aShort[0]} != $bShort" + + aInt[0]++ + bInt++ + if (aInt[0] != bInt) return "Failed post-increment Int: ${aInt[0]} != $bInt" + + aInt[0]-- + bInt-- + if (aInt[0] != bInt) return "Failed post-decrement Int: ${aInt[0]} != $bInt" + + aLong[0]++ + bLong++ + if (aLong[0] != bLong) return "Failed post-increment Long: ${aLong[0]} != $bLong" + + aLong[0]-- + bLong-- + if (aLong[0] != bLong) return "Failed post-decrement Long: ${aLong[0]} != $bLong" + + aFloat[0]++ + bFloat++ + if (aFloat[0] != bFloat) return "Failed post-increment Float: ${aFloat[0]} != $bFloat" + + aFloat[0]-- + bFloat-- + if (aFloat[0] != bFloat) return "Failed post-decrement Float: ${aFloat[0]} != $bFloat" + + aDouble[0]++ + bDouble++ + if (aDouble[0] != bDouble) return "Failed post-increment Double: ${aDouble[0]} != $bDouble" + + aDouble[0]-- + bDouble-- + if (aDouble[0] != bDouble) return "Failed post-decrement Double: ${aDouble[0]} != $bDouble" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/increment/memberExtOnLong.kt b/backend.native/tests/external/codegen/blackbox/increment/memberExtOnLong.kt new file mode 100644 index 00000000000..c51bf9b901d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/memberExtOnLong.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME + +object ExtProvider { + operator fun Long.get(i: Int) = this + operator fun Long.set(i: Int, newValue: Long) {} +} + +fun box(): String { + with (ExtProvider) { + var x = 0L + val y = x[0]++ + return if (y == 0L) "OK" else "Failed, y=$y" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/increment/mutableListElement.kt b/backend.native/tests/external/codegen/blackbox/increment/mutableListElement.kt new file mode 100644 index 00000000000..b861d31e15d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/mutableListElement.kt @@ -0,0 +1,83 @@ +// WITH_RUNTIME + +fun box(): String { + val aByte = arrayListOf(1) + var bByte: Byte = 1 + + val aShort = arrayListOf(1) + var bShort: Short = 1 + + val aInt = arrayListOf(1) + var bInt: Int = 1 + + val aLong = arrayListOf(1) + var bLong: Long = 1 + + val aFloat = arrayListOf(1.0f) + var bFloat: Float = 1.0f + + val aDouble = arrayListOf(1.0) + var bDouble: Double = 1.0 + + aByte[0]-- + bByte-- + + if (aByte[0] != bByte) return "Failed post-decrement Byte: ${aByte[0]} != $bByte" + + aByte[0]++ + bByte++ + + if (aByte[0] != bByte) return "Failed post-increment Byte: ${aByte[0]} != $bByte" + + aShort[0]-- + bShort-- + + if (aShort[0] != bShort) return "Failed post-decrement Short: ${aShort[0]} != $bShort" + + aShort[0]++ + bShort++ + + if (aShort[0] != bShort) return "Failed post-increment Short: ${aShort[0]} != $bShort" + + aInt[0]-- + bInt-- + + if (aInt[0] != bInt) return "Failed post-decrement Int: ${aInt[0]} != $bInt" + + aInt[0]++ + bInt++ + + if (aInt[0] != bInt) return "Failed post-increment Int: ${aInt[0]} != $bInt" + + aLong[0]-- + bLong-- + + if (aLong[0] != bLong) return "Failed post-decrement Long: ${aLong[0]} != $bLong" + + aLong[0]++ + bLong++ + + if (aLong[0] != bLong) return "Failed post-increment Long: ${aLong[0]} != $bLong" + + aFloat[0]-- + bFloat-- + + if (aFloat[0] != bFloat) return "Failed post-decrement Float: ${aFloat[0]} != $bFloat" + + aFloat[0]++ + bFloat++ + + if (aFloat[0] != bFloat) return "Failed post-increment Float: ${aFloat[0]} != $bFloat" + + aDouble[0]-- + bDouble-- + + if (aDouble[0] != bDouble) return "Failed post-decrement Double: ${aDouble[0]} != $bDouble" + + aDouble[0]++ + bDouble++ + + if (aDouble[0] != bDouble) return "Failed post-increment Double: ${aDouble[0]} != $bDouble" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/increment/nullable.kt b/backend.native/tests/external/codegen/blackbox/increment/nullable.kt new file mode 100644 index 00000000000..4802b8a7fbc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/nullable.kt @@ -0,0 +1,69 @@ +fun box(): String { + var aByte: Byte? = 0 + var bByte: Byte = 0 + + var aShort: Short? = 0 + var bShort: Short = 0 + + var aInt: Int? = 0 + var bInt: Int = 0 + + var aLong: Long? = 0 + var bLong: Long = 0 + + var aFloat: Float? = 0.0f + var bFloat: Float = 0.0f + + var aDouble: Double? = 0.0 + var bDouble: Double = 0.0 + + if (aByte != null) aByte-- + bByte-- + if (aByte != bByte) return "Failed post-decrement Byte: $aByte != $bByte" + + if (aByte != null) aByte++ + bByte++ + if (aByte != bByte) return "Failed post-increment Byte: $aByte != $bByte" + + if (aShort != null) aShort-- + bShort-- + if (aShort != bShort) return "Failed post-decrement Short: $aShort != $bShort" + + if (aShort != null) aShort++ + bShort++ + if (aShort != bShort) return "Failed post-increment Short: $aShort != $bShort" + + if (aInt != null) aInt-- + bInt-- + if (aInt != bInt) return "Failed post-decrement Int: $aInt != $bInt" + + if (aInt != null) aInt++ + bInt++ + if (aInt != bInt) return "Failed post-increment Int: $aInt != $bInt" + + if (aLong != null) aLong-- + bLong-- + if (aLong != bLong) return "Failed post-decrement Long: $aLong != $bLong" + + if (aLong != null) aLong++ + bLong++ + if (aLong != bLong) return "Failed post-increment Long: $aLong != $bLong" + + if (aFloat != null) aFloat-- + bFloat-- + if (aFloat != bFloat) return "Failed post-decrement Float: $aFloat != $bFloat" + + if (aFloat != null) aFloat++ + bFloat++ + if (aFloat != bFloat) return "Failed post-increment Float: $aFloat != $bFloat" + + if (aDouble != null) aDouble-- + bDouble-- + if (aDouble != bDouble) return "Failed post-decrement Double: $aDouble != $bDouble" + + if (aDouble != null) aDouble++ + bDouble++ + if (aDouble != bDouble) return "Failed post-increment Double: $aDouble != $bDouble" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/increment/postfixIncrementDoubleSmartCast.kt b/backend.native/tests/external/codegen/blackbox/increment/postfixIncrementDoubleSmartCast.kt new file mode 100644 index 00000000000..738a31c9697 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/postfixIncrementDoubleSmartCast.kt @@ -0,0 +1,10 @@ +public fun box() : String { + var i : Int? + i = 10 + // We have "double" smart cast here: + // first on i and second on i++ + // Back-end should NOT think that both i and j are Int + val j: Int = i++ + + return if (j == 10 && 11 == i) "OK" else "fail j = $j i = $i" +} diff --git a/backend.native/tests/external/codegen/blackbox/increment/postfixIncrementOnClass.kt b/backend.native/tests/external/codegen/blackbox/increment/postfixIncrementOnClass.kt new file mode 100644 index 00000000000..deb8df65d80 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/postfixIncrementOnClass.kt @@ -0,0 +1,12 @@ +interface Base +class Derived: Base +class Another: Base +operator fun Base.inc(): Derived { return Derived() } + +public fun box() : String { + var i : Base + i = Another() + val j = i++ + + return if (j is Another && i is Derived) "OK" else "fail j = $j i = $i" +} diff --git a/backend.native/tests/external/codegen/blackbox/increment/postfixIncrementOnClassSmartCast.kt b/backend.native/tests/external/codegen/blackbox/increment/postfixIncrementOnClassSmartCast.kt new file mode 100644 index 00000000000..3bc2442a3be --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/postfixIncrementOnClassSmartCast.kt @@ -0,0 +1,11 @@ +open class Base +class Derived: Base() +operator fun Derived.inc(): Derived { return Derived() } + +public fun box() : String { + var i : Base + i = Derived() + val j = i++ + + return if (j is Derived && i is Derived) "OK" else "fail j = $j i = $i" +} diff --git a/backend.native/tests/external/codegen/blackbox/increment/postfixIncrementOnShortSmartCast.kt b/backend.native/tests/external/codegen/blackbox/increment/postfixIncrementOnShortSmartCast.kt new file mode 100644 index 00000000000..0dec61d0503 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/postfixIncrementOnShortSmartCast.kt @@ -0,0 +1,8 @@ +public fun box() : String { + var i : Short? + i = 10 + // Postfix increment on a smart casted short should work + val j = i++ + + return if (j!!.toInt() == 10 && i!!.toInt() == 11) "OK" else "fail j = $j i = $i" +} diff --git a/backend.native/tests/external/codegen/blackbox/increment/postfixIncrementOnSmartCast.kt b/backend.native/tests/external/codegen/blackbox/increment/postfixIncrementOnSmartCast.kt new file mode 100644 index 00000000000..3da28a2d6e6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/postfixIncrementOnSmartCast.kt @@ -0,0 +1,9 @@ +public fun box() : String { + var i : Int? + i = 10 + // Postfix increment on a smart cast should work + // Specific: i.inc() type is Int but i and j types are both Int? + val j = i++ + + return if (j == 10 && 11 == i) "OK" else "fail j = $j i = $i" +} diff --git a/backend.native/tests/external/codegen/blackbox/increment/postfixNullableClassIncrement.kt b/backend.native/tests/external/codegen/blackbox/increment/postfixNullableClassIncrement.kt new file mode 100644 index 00000000000..b6d22b07a1b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/postfixNullableClassIncrement.kt @@ -0,0 +1,11 @@ +class MyClass + +operator fun MyClass?.inc(): MyClass? = null + +public fun box() : String { + var i : MyClass? + i = MyClass() + val j = i++ + + return if (j is MyClass && null == i) "OK" else "fail i = $i j = $j" +} diff --git a/backend.native/tests/external/codegen/blackbox/increment/postfixNullableIncrement.kt b/backend.native/tests/external/codegen/blackbox/increment/postfixNullableIncrement.kt new file mode 100644 index 00000000000..2564e3ed898 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/postfixNullableIncrement.kt @@ -0,0 +1,10 @@ +operator fun Int?.inc(): Int? = this + +fun init(): Int? { return 10 } + +public fun box() : String { + var i : Int? = init() + val j = i++ + + return if (j == 10 && 10 == i) "OK" else "fail i = $i j = $j" +} diff --git a/backend.native/tests/external/codegen/blackbox/increment/prefixIncrementOnClass.kt b/backend.native/tests/external/codegen/blackbox/increment/prefixIncrementOnClass.kt new file mode 100644 index 00000000000..6bc75ad060e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/prefixIncrementOnClass.kt @@ -0,0 +1,12 @@ +interface Base +class Derived: Base +class Another: Base +operator fun Base.inc(): Derived { return Derived() } + +public fun box() : String { + var i : Base + i = Another() + val j = ++i + + return if (j is Derived && i is Derived) "OK" else "fail j = $j i = $i" +} diff --git a/backend.native/tests/external/codegen/blackbox/increment/prefixIncrementOnClassSmartCast.kt b/backend.native/tests/external/codegen/blackbox/increment/prefixIncrementOnClassSmartCast.kt new file mode 100644 index 00000000000..c51f6d1d816 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/prefixIncrementOnClassSmartCast.kt @@ -0,0 +1,11 @@ +open class Base +class Derived: Base() +operator fun Derived.inc(): Derived { return Derived() } + +public fun box() : String { + var i : Base + i = Derived() + val j = ++i + + return if (j is Derived && i is Derived) "OK" else "fail j = $j i = $i" +} diff --git a/backend.native/tests/external/codegen/blackbox/increment/prefixIncrementOnSmartCast.kt b/backend.native/tests/external/codegen/blackbox/increment/prefixIncrementOnSmartCast.kt new file mode 100644 index 00000000000..80e48f4f78b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/prefixIncrementOnSmartCast.kt @@ -0,0 +1,8 @@ +public fun box() : String { + var i : Int? + i = 10 + // Prefix increment on a smart cast should work + val j = ++i + + return if (j == 11 && 11 == i) "OK" else "fail j = $j i = $i" +} diff --git a/backend.native/tests/external/codegen/blackbox/increment/prefixNullableClassIncrement.kt b/backend.native/tests/external/codegen/blackbox/increment/prefixNullableClassIncrement.kt new file mode 100644 index 00000000000..e8c98d7bce6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/prefixNullableClassIncrement.kt @@ -0,0 +1,11 @@ +class MyClass + +operator fun MyClass?.inc(): MyClass? = null + +public fun box() : String { + var i : MyClass? + i = MyClass() + val j = ++i + + return if (j == null && null == i) "OK" else "fail i = $i j = $j" +} diff --git a/backend.native/tests/external/codegen/blackbox/increment/prefixNullableIncrement.kt b/backend.native/tests/external/codegen/blackbox/increment/prefixNullableIncrement.kt new file mode 100644 index 00000000000..2c28b62ff11 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/increment/prefixNullableIncrement.kt @@ -0,0 +1,10 @@ +operator fun Int?.inc(): Int? = this + +fun init(): Int? { return 10 } + +public fun box() : String { + var i : Int? = init() + val j = ++i + + return if (j == 10 && 10 == i) "OK" else "fail i = $i j = $j" +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/createNestedClass.kt b/backend.native/tests/external/codegen/blackbox/innerNested/createNestedClass.kt new file mode 100644 index 00000000000..b5cd0e787ec --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/createNestedClass.kt @@ -0,0 +1,13 @@ +class A { + class B1 + class B2(val x: Int) + class B3(val x: Long, val y: Int) + class B4(val str: String) +} + + +fun box(): String { + A.B1() + val b2 = A.B2(A.B3(42, 42).y) + return A.B4("OK").str +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/createdNestedInOuterMember.kt b/backend.native/tests/external/codegen/blackbox/innerNested/createdNestedInOuterMember.kt new file mode 100644 index 00000000000..f4c0640c7ab --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/createdNestedInOuterMember.kt @@ -0,0 +1,14 @@ +fun foo(f: (Int) -> Int) = f(0) + +class Outer { + class Nested { + val y = foo { a -> a } + } + + fun bar(): String { + val a = Nested() + return "OK" + } +} + +fun box() = Outer().bar() diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/extensionFun.kt b/backend.native/tests/external/codegen/blackbox/innerNested/extensionFun.kt new file mode 100644 index 00000000000..44ed11116dc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/extensionFun.kt @@ -0,0 +1,31 @@ +class Outer { + class Nested + inner class Inner + + fun Inner.foo() { + Outer() + Nested() + Inner() + } + + fun Nested.bar() { + Outer() + Nested() + Inner() + } + + fun Outer.baz() { + Outer() + Nested() + Inner() + } + + fun box(): String { + Inner().foo() + Nested().bar() + baz() + return "OK" + } +} + +fun box() = Outer().box() diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/extensionToNested.kt b/backend.native/tests/external/codegen/blackbox/innerNested/extensionToNested.kt new file mode 100644 index 00000000000..553ff99ae00 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/extensionToNested.kt @@ -0,0 +1,9 @@ +class Test { + class Nested { + val value = "OK" + } +} + +fun Test.Nested.foo() = value + +fun box() = Test.Nested().foo() diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/importNestedClass.kt b/backend.native/tests/external/codegen/blackbox/innerNested/importNestedClass.kt new file mode 100644 index 00000000000..8bb9fdc5376 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/importNestedClass.kt @@ -0,0 +1,18 @@ +import A.B +import A.B.C + +class A { + class B { + class C + } +} + +fun box(): String { + val a = A() + val b = B() + val ab = A.B() + val c = C() + val bc = B.C() + val abc = A.B.C() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/innerGeneric.kt b/backend.native/tests/external/codegen/blackbox/innerNested/innerGeneric.kt new file mode 100644 index 00000000000..36a6bda1e99 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/innerGeneric.kt @@ -0,0 +1,11 @@ +class Outer { + inner class Inner(val t: T) { + fun box() = t + } +} + +fun box(): String { + if (Outer().Inner("OK").box() != "OK") return "Fail" + val x: Outer.Inner = Outer().Inner("OK") + return x.box() +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/innerGenericClassFromJava.kt b/backend.native/tests/external/codegen/blackbox/innerNested/innerGenericClassFromJava.kt new file mode 100644 index 00000000000..3490ee65894 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/innerGenericClassFromJava.kt @@ -0,0 +1,26 @@ +// TARGET_BACKEND: JVM +// FILE: JavaClass.java + +public abstract class JavaClass { + public static String test() { + return Test.INSTANCE.foo(new Outer("OK").new Inner(1)); + } +} + +// FILE: Kotlin.kt + +class Outer(val x: E) { + inner class Inner(val y: F) { + fun foo() = x.toString() + y.toString() + } +} + +object Test { + fun foo(x: Outer.Inner) = x.foo() +} + +fun box(): String { + val result = JavaClass.test() + if (result != "OK1") return "Fail: $result" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/innerJavaClass.kt b/backend.native/tests/external/codegen/blackbox/innerNested/innerJavaClass.kt new file mode 100644 index 00000000000..da291521d05 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/innerJavaClass.kt @@ -0,0 +1,22 @@ +// TARGET_BACKEND: JVM +// FILE: JavaClass.java + +public abstract class JavaClass { + public abstract InnerClass onCreateInner(); + + public class InnerClass { + + } +} + +// FILE: Kotlin.kt + +public class MyWallpaperService : JavaClass() { + override fun onCreateInner(): JavaClass.InnerClass = MyEngine() + + private inner class MyEngine : JavaClass.InnerClass() +} + +fun box(): String { + return if (MyWallpaperService().onCreateInner() != null) return "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/innerLabeledThis.kt b/backend.native/tests/external/codegen/blackbox/innerNested/innerLabeledThis.kt new file mode 100644 index 00000000000..34a50d00af6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/innerLabeledThis.kt @@ -0,0 +1,11 @@ +class Outer { + inner class Inner { + fun O() = this@Outer.O + val K = this@Outer.K() + } + + val O = "O" + fun K() = "K" +} + +fun box() = Outer().Inner().O() + Outer().Inner().K diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/innerSimple.kt b/backend.native/tests/external/codegen/blackbox/innerNested/innerSimple.kt new file mode 100644 index 00000000000..9159e24d84c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/innerSimple.kt @@ -0,0 +1,7 @@ +class Outer { + inner class Inner { + fun box() = "OK" + } +} + +fun box() = Outer().Inner().box() diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/kt3132.kt b/backend.native/tests/external/codegen/blackbox/innerNested/kt3132.kt new file mode 100644 index 00000000000..afcee1c6ca1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/kt3132.kt @@ -0,0 +1,13 @@ +class Test { + interface Foo { } + + class FooImplNested: Foo { } + + inner class FooImplInner: Foo { } +} + +fun box(): String { + Test().FooImplInner() + Test.FooImplNested() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/kt3927.kt b/backend.native/tests/external/codegen/blackbox/innerNested/kt3927.kt new file mode 100644 index 00000000000..1e1efce9624 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/kt3927.kt @@ -0,0 +1,23 @@ +//KT-3927 Inner class cannot be instantiated with child instance of outer class + +abstract class Base { + inner class Inner { + fun o() = "O" + fun k() = "K" + } +} + +class Child : Base() + +fun box(): String { + var result = "" + result += Child().Inner().o() + + fun Child.f() { + result += Inner().k() + } + Child().f() + + return result +} + diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/kt5363.kt b/backend.native/tests/external/codegen/blackbox/innerNested/kt5363.kt new file mode 100644 index 00000000000..1f696893d3d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/kt5363.kt @@ -0,0 +1,13 @@ +class Outer { + class Nested{ + fun foo(s: String) = s.extension() + } + + companion object { + private fun String.extension(): String = this + } +} + +fun box(): String { + return Outer.Nested().foo("OK") +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/kt6804.kt b/backend.native/tests/external/codegen/blackbox/innerNested/kt6804.kt new file mode 100644 index 00000000000..edb201a622e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/kt6804.kt @@ -0,0 +1,13 @@ +class Outer { + class Nested { + fun fn() = s + } + + companion object { + private val s = "OK" + } +} + +fun box(): String { + return Outer.Nested().fn() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/nestedClassInObject.kt b/backend.native/tests/external/codegen/blackbox/innerNested/nestedClassInObject.kt new file mode 100644 index 00000000000..ec3f72d4b20 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/nestedClassInObject.kt @@ -0,0 +1,10 @@ +object A { + class B + class C +} + +fun box(): String { + val b = A.B() + val c = A.C() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/nestedClassObject.kt b/backend.native/tests/external/codegen/blackbox/innerNested/nestedClassObject.kt new file mode 100644 index 00000000000..8e470a4e58e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/nestedClassObject.kt @@ -0,0 +1,12 @@ +class Outer { + class Nested { + companion object { + val O = "O" + val K = "K" + } + } + + fun O() = Nested.O +} + +fun box() = Outer().O() + Outer.Nested.K diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/nestedEnumConstant.kt b/backend.native/tests/external/codegen/blackbox/innerNested/nestedEnumConstant.kt new file mode 100644 index 00000000000..d8ae583f3d5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/nestedEnumConstant.kt @@ -0,0 +1,8 @@ +class Outer { + enum class Nested { + O, + K + } +} + +fun box() = "${Outer.Nested.O}${Outer.Nested.K}" diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/nestedGeneric.kt b/backend.native/tests/external/codegen/blackbox/innerNested/nestedGeneric.kt new file mode 100644 index 00000000000..9cdea6814f5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/nestedGeneric.kt @@ -0,0 +1,12 @@ +class Outer { + class Nested(val t: T) { + fun box() = t + } +} + +fun box(): String { + if (Outer.Nested("OK").box() != "OK") return "Fail" + + val x: Outer.Nested = Outer.Nested("OK") + return x.box() +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/nestedInPackage.kt b/backend.native/tests/external/codegen/blackbox/innerNested/nestedInPackage.kt new file mode 100644 index 00000000000..a08a2098110 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/nestedInPackage.kt @@ -0,0 +1,10 @@ +package Package + +class Outer { + class Nested { + val O = "O" + val K = "K" + } +} + +fun box() = Package.Outer.Nested().O + Outer.Nested().K diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/nestedObjects.kt b/backend.native/tests/external/codegen/blackbox/innerNested/nestedObjects.kt new file mode 100644 index 00000000000..185af172991 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/nestedObjects.kt @@ -0,0 +1,9 @@ +object A { + object B { + object C { + val ok = "OK" + } + } +} + +fun box() = A.B.C.ok diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/nestedSimple.kt b/backend.native/tests/external/codegen/blackbox/innerNested/nestedSimple.kt new file mode 100644 index 00000000000..a9180148616 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/nestedSimple.kt @@ -0,0 +1,7 @@ +class Outer { + class Nested { + fun box() = "OK" + } +} + +fun box() = Outer.Nested().box() diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/protectedNestedClass.kt b/backend.native/tests/external/codegen/blackbox/innerNested/protectedNestedClass.kt new file mode 100644 index 00000000000..7de7c5cf0a6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/protectedNestedClass.kt @@ -0,0 +1,25 @@ +// See KT-9246 IllegalAccessError when trying to access protected nested class from parent class +// FILE: a.kt + +package a + +abstract class A { + protected class C { + fun result() = "OK" + } +} + +// FILE: b.kt + +package b + +import a.A + +class B : A() { + protected val c = A.C() + val result: String get() = c.result() +} + +fun box(): String { + return B().result +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/protectedNestedClassFromJava.kt b/backend.native/tests/external/codegen/blackbox/innerNested/protectedNestedClassFromJava.kt new file mode 100644 index 00000000000..1dbc087f9c9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/protectedNestedClassFromJava.kt @@ -0,0 +1,34 @@ +// See KT-8269 java.lang.IllegalAccessError on accessing protected inner class declared in Kotlin super class +// TARGET_BACKEND: JVM +// FILE: Test.kt + +package com.company + +import other.JavaClass + +open class Test { + protected class ProtectedClass +} + +fun box(): String { + JavaClass.test() + return "OK" +} + +// FILE: other/JavaClass.java + +package other; + +import com.company.Test; + +public class JavaClass { + static class JavaTest extends Test { + public static boolean foo(Object obj) { + return obj instanceof ProtectedClass; + } + } + + public static void test() { + JavaTest.foo(new Object()); + } +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/deepInnerHierarchy.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/deepInnerHierarchy.kt new file mode 100644 index 00000000000..08efa14a7ff --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/deepInnerHierarchy.kt @@ -0,0 +1,13 @@ +open class A(val s: String) { + open inner class B(s: String): A(s) + + open inner class C(s: String, additional: Double): B(s) + + open inner class D(other: Int, another: Long, s: String) : C(s, another.toDouble()) + + open inner class E : D(0, 42L, "OK") + + inner class F : E() +} + +fun box(): String = A("Fail").F().s diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/deepLocalHierarchy.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/deepLocalHierarchy.kt new file mode 100644 index 00000000000..760f7b0deae --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/deepLocalHierarchy.kt @@ -0,0 +1,17 @@ +fun box(): String { + abstract class L1 { + abstract fun foo(): String + } + + open class L2(val s: String) : L1() { + override fun foo() = s + } + + open class L3(unused: Double, value: String = "OK") : L2(value) + + open class L4(i: Int, j: Long, z: Boolean, l: L3) : L3(3.14) + + class L5 : L4(0, 0L, false, L3(2.71, "Fail")) + + return L5().foo() +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/innerExtendsInnerViaSecondaryConstuctor.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/innerExtendsInnerViaSecondaryConstuctor.kt new file mode 100644 index 00000000000..c218f292c1f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/innerExtendsInnerViaSecondaryConstuctor.kt @@ -0,0 +1,17 @@ +open class Father(val param: String) { + abstract inner class InClass { + fun work(): String { + return param + } + } + + inner class Child(p: String) : Father(p) { + inner class Child2 : Father.InClass { + constructor(): super() + } + } +} + +fun box(): String { + return Father("fail").Child("OK").Child2().work() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/innerExtendsInnerWithProperOuterCapture.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/innerExtendsInnerWithProperOuterCapture.kt new file mode 100644 index 00000000000..3dd19c2f3d5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/innerExtendsInnerWithProperOuterCapture.kt @@ -0,0 +1,17 @@ +open class Father(val param: String) { + abstract inner class InClass { + fun work(): String { + return param + } + } + + inner class Child(p: String) : Father(p) { + inner class Child2 : Father.InClass() { + + } + } +} + +fun box(): String { + return Father("fail").Child("OK").Child2().work() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/innerExtendsOuter.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/innerExtendsOuter.kt new file mode 100644 index 00000000000..8db3bfa10ca --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/innerExtendsOuter.kt @@ -0,0 +1,15 @@ +// TARGET_BACKEND: JVM + +// When inner class extends its outer, there are two instances of the outer present in the inner: +// the enclosing one and the one in the super call. +// Here we test that symbols are resolved to the instance created via the super call. + +open class Outer(vararg val chars: Char) { + open inner class Inner(val s: String): Outer(s[0], s[1]) { + fun concat() = java.lang.String.valueOf(chars) + } + + fun value() = Inner("OK").concat() +} + +fun box() = Outer('F', 'a', 'i', 'l').value() diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/kt11833_1.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/kt11833_1.kt new file mode 100644 index 00000000000..fe17fb4d085 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/kt11833_1.kt @@ -0,0 +1,17 @@ +abstract class Father { + abstract inner class InClass { + abstract fun work(): String + } +} + +class Child : Father() { + val ChildInClass = object : Father.InClass() { + override fun work(): String { + return "OK" + } + } +} + +fun box(): String { + return Child().ChildInClass.work() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/kt11833_2.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/kt11833_2.kt new file mode 100644 index 00000000000..4753541d860 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/kt11833_2.kt @@ -0,0 +1,19 @@ +abstract class Father { + abstract inner class InClass { + abstract fun work(): String + } +} + +class Child : Father() { + fun test(): InClass { + return object : Father.InClass() { + override fun work(): String { + return "OK" + } + } + } +} + +fun box(): String { + return Child().test().work() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/localClassOuterDiffersFromInnerOuter.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/localClassOuterDiffersFromInnerOuter.kt new file mode 100644 index 00000000000..cf1db10e27c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/localClassOuterDiffersFromInnerOuter.kt @@ -0,0 +1,17 @@ +class A { + fun bar(): Any { + return { + { + class Local : Inner() { + override fun toString() = foo() + } + Local() + }() + }() + } + + open inner class Inner + fun foo() = "OK" +} + +fun box(): String = A().bar().toString() diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/localExtendsInner.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/localExtendsInner.kt new file mode 100644 index 00000000000..bd2fe48d847 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/localExtendsInner.kt @@ -0,0 +1,21 @@ +open class Father(val param: String) { + abstract inner class InClass { + fun work(): String { + return param + } + } + + inner class Child(p: String) : Father(p) { + fun test(): InClass { + class Local : Father.InClass() { + + } + return Local() + } + + } +} + +fun box(): String { + return Father("fail").Child("OK").test().work() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/localExtendsLocalWithClosure.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/localExtendsLocalWithClosure.kt new file mode 100644 index 00000000000..f24ed933d5c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/localExtendsLocalWithClosure.kt @@ -0,0 +1,11 @@ +fun box(): String { + val result = "OK" + + open class Local(val ok: Boolean) { + fun result() = if (ok) result else "Fail" + } + + class Derived : Local(true) + + return Derived().result() +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/localWithClosureExtendsLocalWithClosure.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/localWithClosureExtendsLocalWithClosure.kt new file mode 100644 index 00000000000..b2bb6dbd67a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/localWithClosureExtendsLocalWithClosure.kt @@ -0,0 +1,16 @@ +fun box(): String { + val three = 3 + + open class Local(val one: Int) { + open fun value() = "$three$one" + } + + val four = 4 + + class Derived(val two: Int) : Local(1) { + override fun value() = super.value() + "$four$two" + } + + val result = Derived(2).value() + return if (result == "3142") "OK" else "Fail: $result" +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsClassDefaultArgument.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsClassDefaultArgument.kt new file mode 100644 index 00000000000..298b0ec9162 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsClassDefaultArgument.kt @@ -0,0 +1,9 @@ +// KT-3581 + +open class A(val result: String = "OK") { +} + +fun box(): String { + val a = object : A() {} + return a.result +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsClassVararg.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsClassVararg.kt new file mode 100644 index 00000000000..b0bb4aed5d1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsClassVararg.kt @@ -0,0 +1,8 @@ +open class SomeClass(val some: Double, val other: Int, vararg val args: String) { + fun result() = args[1] +} + +fun box(): String { + return object : SomeClass(3.14, 42, "No", "OK", "Yes") { + }.result() +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsInner.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsInner.kt new file mode 100644 index 00000000000..f02f1d4edc1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsInner.kt @@ -0,0 +1,12 @@ +class A { + open inner class Inner(val result: String) + + fun box(): String { + val o = object : Inner("OK") { + fun ok() = result + } + return o.ok() + } +} + +fun box() = A().box() diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsInnerDefaultArgument.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsInnerDefaultArgument.kt new file mode 100644 index 00000000000..c94d6ab49ca --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsInnerDefaultArgument.kt @@ -0,0 +1,12 @@ +class A { + open inner class Inner(val result: String = "OK", val int: Int) + + fun box(): String { + val o = object : Inner(int = 0) { + fun ok() = result + } + return o.ok() + } +} + +fun box() = A().box() diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsInnerOfLocalVarargAndDefault.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsInnerOfLocalVarargAndDefault.kt new file mode 100644 index 00000000000..eef3131ae2b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsInnerOfLocalVarargAndDefault.kt @@ -0,0 +1,17 @@ +fun box(): String { + val capture = "oh" + + class Local { + val captured = capture + + open inner class Inner(val d: Double = -1.0, val s: String, vararg val y: Int) { + open fun result() = "Fail" + } + + val obj = object : Inner(s = "OK") { + override fun result() = s + } + } + + return Local().obj.result() +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsInnerOfLocalWithCapture.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsInnerOfLocalWithCapture.kt new file mode 100644 index 00000000000..b4fb7a47cee --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsInnerOfLocalWithCapture.kt @@ -0,0 +1,15 @@ +fun box(): String { + class Local { + open inner class Inner(val s: String) { + open fun result() = "Fail" + } + + val realResult = "OK" + + val obj = object : Inner(realResult) { + override fun result() = s + } + } + + return Local().obj.result() +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsLocalCaptureInSuperCall.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsLocalCaptureInSuperCall.kt new file mode 100644 index 00000000000..35bb545eb82 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsLocalCaptureInSuperCall.kt @@ -0,0 +1,11 @@ +open class A(val s: String) + +fun box(): String { + class B { + val result = "OK" + + val f = object : A(result) {}.s + } + + return B().f +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsLocalWithClosure.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsLocalWithClosure.kt new file mode 100644 index 00000000000..834b1e5d824 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectExtendsLocalWithClosure.kt @@ -0,0 +1,14 @@ +fun box(): String { + val d = 42.0 + val c = 'C' + + open class Local(val l: Long) { + fun foo(): Boolean = d == 42.0 && c == 'C' && l == 239L + } + + if (object : Local(239L) { + fun bar(): Boolean = foo() + }.bar()) return "OK" + + return "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectOuterDiffersFromInnerOuter.kt b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectOuterDiffersFromInnerOuter.kt new file mode 100644 index 00000000000..e6fe2b05cf9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/innerNested/superConstructorCall/objectOuterDiffersFromInnerOuter.kt @@ -0,0 +1,16 @@ +class A { + fun bar(): Any { + return { + { + object : Inner() { + override fun toString() = foo() + } + }() + }() + } + + open inner class Inner + fun foo() = "OK" +} + +fun box(): String = A().bar().toString() diff --git a/backend.native/tests/external/codegen/blackbox/instructions/swap/swapRefToSharedVarInt.kt b/backend.native/tests/external/codegen/blackbox/instructions/swap/swapRefToSharedVarInt.kt new file mode 100644 index 00000000000..619bfd3a800 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/instructions/swap/swapRefToSharedVarInt.kt @@ -0,0 +1,11 @@ +fun box(): String { + var a: Int + a = 12 + fun f() { + foo(a) + } + + return "OK" +} + +fun foo(l: Int) {} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/instructions/swap/swapRefToSharedVarLong.kt b/backend.native/tests/external/codegen/blackbox/instructions/swap/swapRefToSharedVarLong.kt new file mode 100644 index 00000000000..7340eb15d14 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/instructions/swap/swapRefToSharedVarLong.kt @@ -0,0 +1,13 @@ +//KT-3042 Attempt to split long or double on the stack excepion + +fun box(): String { + var a: Long + a = 12.toLong() + fun f() { + foo(a) + } + + return "OK" +} + +fun foo(l: Long) {} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/charToInt.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/charToInt.kt new file mode 100644 index 00000000000..371632e071c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/charToInt.kt @@ -0,0 +1,8 @@ +fun box(): String { + val x: Any = 'A' + var y = 0 + if (x is Char) { + y = x.toInt() + } + return if (y == 65) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/defaultObjectMapping.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/defaultObjectMapping.kt new file mode 100644 index 00000000000..93684dbed0d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/defaultObjectMapping.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + assertEquals(java.lang.Integer.MIN_VALUE, Int.MIN_VALUE) + assertEquals(java.lang.Byte.MAX_VALUE, Byte.MAX_VALUE) + +/* +// TODO: uncomment when callable references to object members are supported + assertEquals("MIN_VALUE", (Int.Companion::MIN_VALUE).name) + assertEquals("MAX_VALUE", (Double.Companion::MAX_VALUE).name) + assertEquals("MIN_VALUE", (Float.Companion::MIN_VALUE).name) + assertEquals("MAX_VALUE", (Long.Companion::MAX_VALUE).name) + assertEquals("MIN_VALUE", (Short.Companion::MIN_VALUE).name) + assertEquals("MAX_VALUE", (Byte.Companion::MAX_VALUE).name) +*/ + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/ea35953.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/ea35953.kt new file mode 100644 index 00000000000..a1acb1d7481 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/ea35953.kt @@ -0,0 +1,6 @@ +fun box(): String { + if (12.toString().equals("13")) { + return "Fail" + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/incWithLabel.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/incWithLabel.kt new file mode 100644 index 00000000000..fff72ffb135 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/incWithLabel.kt @@ -0,0 +1,8 @@ +fun box(): String { + var x = 1 + (foo@ x)++ + ++(foo@ x) + + if (x != 3) return "Fail: $x" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/kt10131.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/kt10131.kt new file mode 100644 index 00000000000..0977be5cb27 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/kt10131.kt @@ -0,0 +1,7 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String = + listOf('O', 'K').fold("", String::plus) diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/kt10131a.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/kt10131a.kt new file mode 100644 index 00000000000..47eb9d0c65d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/kt10131a.kt @@ -0,0 +1,7 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String = + charArrayOf('O', 'K').fold("", String::plus) diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/kt12125.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/kt12125.kt new file mode 100644 index 00000000000..c45ffb3f57c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/kt12125.kt @@ -0,0 +1,17 @@ +fun test(i: Int): Int { + return i +} + +fun box(): String { + var b = Byte.MAX_VALUE + b++ + var result = test(b.toInt()) + if (result != Byte.MIN_VALUE.toInt()) return "fail 1: $result" + + var s = Short.MIN_VALUE + s-- + result = test(s.toInt()) + if (result != Short.MAX_VALUE.toInt()) return "fail 2: $result" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/kt12125_2.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/kt12125_2.kt new file mode 100644 index 00000000000..c9890efe644 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/kt12125_2.kt @@ -0,0 +1,16 @@ +fun box(): String { + var aByte: Byte? = 0 + var bByte: Byte = 0 + + if (aByte != null) aByte-- + bByte-- + if (aByte != bByte) return "Failed post-decrement Byte: $aByte != $bByte" + + if (aByte != null) aByte++ + bByte++ + if (aByte != bByte) return "Failed post-increment Byte: $aByte != $bByte" + + aByte = null + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/kt12125_inc.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/kt12125_inc.kt new file mode 100644 index 00000000000..f531e713ef5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/kt12125_inc.kt @@ -0,0 +1,15 @@ +fun test(i: Int): Int { + return i +} + +fun box(): String { + var b = Byte.MAX_VALUE + var result = test(b.inc().toInt()) + if (result != Byte.MIN_VALUE.toInt()) return "fail 1: $result" + + var s = Short.MAX_VALUE + result = test(s.inc().toInt()) + if (result != Short.MIN_VALUE.toInt()) return "fail 2: $result" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/kt12125_inc_2.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/kt12125_inc_2.kt new file mode 100644 index 00000000000..953ccf8dc76 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/kt12125_inc_2.kt @@ -0,0 +1,20 @@ +fun test(i: Int): Int { + return i +} + +fun box(): String { + var aByte: Byte? = 0 + var bByte: Byte = 0 + + if (aByte != null) { + if (aByte.dec() != bByte.dec()) return "Failed post-decrement Byte: ${aByte.dec()} != ${bByte.dec()}" + } + + if (aByte != null) { + if (aByte.inc() != bByte.inc()) return "Failed post-increment Byte: ${aByte.inc()} != ${bByte.inc()}" + } + + aByte = null + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/kt5937.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/kt5937.kt new file mode 100644 index 00000000000..e83cc48c5c3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/kt5937.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +var result = "Fail" + +var l = 10L +var d = 10.0 +var i = 10 + +fun foo(): Int { + result = "OK" + return 1 +} + +fun box(): String { + val javaClass = foo().javaClass + if (javaClass != 1.javaClass) return "fail 1" + + val lv = 3L + if (2L.javaClass != lv.javaClass) return "fail 2" + if (2L.javaClass != l.javaClass) return "fail 3" + + val dv = 3.0 + if (2.0.javaClass != dv.javaClass) return "fail 4" + if (2.0.javaClass != d.javaClass) return "fail 5" + + val iv = 3 + if (2.javaClass != iv.javaClass) return "fail 6" + if (2.javaClass != i.javaClass) return "fail 7" + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/longRangeWithExplicitDot.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/longRangeWithExplicitDot.kt new file mode 100644 index 00000000000..1ecc929824d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/longRangeWithExplicitDot.kt @@ -0,0 +1,6 @@ +fun box(): String { + val l: Long = 1 + val l2: Long = 2 + val r = l.rangeTo(l2) + return if (r.start == l && r.endInclusive == l2) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/prefixIncDec.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/prefixIncDec.kt new file mode 100644 index 00000000000..612c91f3fa7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/prefixIncDec.kt @@ -0,0 +1,29 @@ +public var inc: Int = 0; + +public var propInc: Int = 0 + get() {++inc; return field} + set(a: Int) { + ++inc + field = a + } + +public var dec: Int = 0; + +public var propDec: Int = 0; + get() { --dec; return field} + set(a: Int) { + --dec + field = a + } + +fun box(): String { + ++propInc + if (inc != 3) return "fail in prefix increment: ${inc} != 3" + if (propInc != 1) return "fail in prefix increment: ${propInc} != 1" + + --propDec + if (dec != -3) return "fail in prefix decrement: ${dec} != -3" + if (propDec != -1) return "fail in prefix decrement: ${propDec} != -1" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/rangeFromCollection.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/rangeFromCollection.kt new file mode 100644 index 00000000000..93d22ce72d0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/rangeFromCollection.kt @@ -0,0 +1,6 @@ +fun box(): String { + val list = ArrayList() + list.add(1..3) + list[0].start + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/stringFromCollection.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/stringFromCollection.kt new file mode 100644 index 00000000000..bd15b7bf3f3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/stringFromCollection.kt @@ -0,0 +1,7 @@ +fun box(): String { + val list = ArrayList() + list.add("0") + list[0][0] + list[0].length + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/throwable.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/throwable.kt new file mode 100644 index 00000000000..bd9e5c754f1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/throwable.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + val s: String? = "OK" + val t: Throwable? = Throwable("test", null) + + val z = Throwable(s, t) + if (z.message !== s) return "fail 1: ${z.message}" + if (z.cause !== t) return "fail 2: ${z.cause}" + + val z2 = Throwable(s) + if (z2.message !== s) return "fail 3: ${z2.message}" + if (z2.cause !== null) return "fail 4: ${z2.cause}" + + val z3 = Throwable(t) + if (z3.message != "java.lang.Throwable: test") return "fail 5: ${z3.message}" + if (z3.cause !== t) return "fail 6: ${z2.cause}" + + val z4 = Throwable() + if (z4.message !== null) return "fail 7: ${z4.message}" + if (z4.cause !== null) return "fail 8: ${z4.cause}" + + return z.message!! +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/throwableCallableReference.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/throwableCallableReference.kt new file mode 100644 index 00000000000..90f3105d6d2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/throwableCallableReference.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +import kotlin.reflect.KFunction2 +import kotlin.reflect.KFunction1 +import kotlin.reflect.KFunction0 + +fun box(): String { + val s: String? = "OK" + val t: Throwable? = Throwable("test", null) + var thr1: KFunction2 = ::Throwable + val z = thr1(s, t) + if (z.message !== s) return "fail 1: ${z.message}" + if (z.cause !== t) return "fail 2: ${z.cause}" + + var thr2: KFunction1 = ::Throwable + + val z2 = thr2(s) + if (z2.message !== s) return "fail 3: ${z2.message}" + if (z2.cause !== null) return "fail 4: ${z2.cause}" + + var thr3: KFunction1 = ::Throwable + val z3 = thr3(t) + if (z3.message != "java.lang.Throwable: test") return "fail 5: ${z3.message}" + if (z3.cause !== t) return "fail 6: ${z2.cause}" + + var thr4: KFunction0 = ::Throwable + val z4 = thr4() + if (z4.message !== null) return "fail 7: ${z4.message}" + if (z4.cause !== null) return "fail 8: ${z4.cause}" + + return z.message!! +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/throwableParamOrder.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/throwableParamOrder.kt new file mode 100644 index 00000000000..351f483c5c6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/throwableParamOrder.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +var res = "" + +fun getM(): String { + res += "M" + return "OK" +} + +fun getT(): Throwable { + res += "T" + return Throwable("test", null) +} + +fun box(): String { + val z = Throwable(cause = getT(), message = getM()) + if (res != "TM") return "Wrong argument calculation order: $res" + return z.message!! +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/intrinsics/tostring.kt b/backend.native/tests/external/codegen/blackbox/intrinsics/tostring.kt new file mode 100644 index 00000000000..4e40b40c9b1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/intrinsics/tostring.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + if (239.toByte().toString() != (239.toByte() as Byte?).toString()) return "byte failed" + if (239.toShort().toString() != (239.toShort() as Short?).toString()) return "short failed" + if (239.toInt().toString() != (239.toInt() as Int?).toString()) return "int failed" + if (239.toFloat().toString() != (239.toFloat() as Float?).toString()) return "float failed" + if (239.toLong().toString() != (239.toLong() as Long?).toString()) return "long failed" + if (239.toDouble().toString() != (239.toDouble() as Double?).toString()) return "double failed" + if (true.toString() != (true as Boolean?).toString()) return "boolean failed" + if ('a'.toChar().toString() != ('a'.toChar() as Char?).toString()) return "char failed" + + if ("${239.toByte()}" != (239.toByte() as Byte?).toString()) return "byte template failed" + if ("${239.toShort()}" != (239.toShort() as Short?).toString()) return "short template failed" + if ("${239.toInt()}" != (239.toInt() as Int?).toString()) return "int template failed" + if ("${239.toFloat()}" != (239.toFloat() as Float?).toString()) return "float template failed" + if ("${239.toLong()}" != (239.toLong() as Long?).toString()) return "long template failed" + if ("${239.toDouble()}" != (239.toDouble() as Double?).toString()) return "double template failed" + if ("${true}" != (true as Boolean?).toString()) return "boolean template failed" + if ("${'a'.toChar()}" != ('a'.toChar() as Char?).toString()) return "char template failed" + + for(b in 0..255) { + if("${b.toByte()}" != (b.toByte() as Byte?).toString()) return "byte conversion failed" + } + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/javaInterop/generics/allWildcardsOnClass.kt b/backend.native/tests/external/codegen/blackbox/javaInterop/generics/allWildcardsOnClass.kt new file mode 100644 index 00000000000..5cba4e58400 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/javaInterop/generics/allWildcardsOnClass.kt @@ -0,0 +1,51 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: JavaClass.java + +public class JavaClass { + + public static class C extends B { + public OutPair foo() { + return super.foo(); + } + + public In bar() { + return super.bar(); + } + } + + public static String test() { + A a = new C(); + + if (!a.foo().getX().equals("OK")) return "fail 1"; + if (!a.foo().getY().equals(123)) return "fail 2"; + + if (!a.bar().make("123").equals("123")) return "fail 3"; + + return "OK"; + } +} + +// FILE: main.kt + +class OutPair(val x: X, val y: Y) +class In { + fun make(x: Z): String = x.toString() +} + +@JvmSuppressWildcards(suppress = false) +interface A { + fun foo(): OutPair + fun bar(): In +} + +abstract class B : A { + override fun foo(): OutPair = OutPair("OK", 123) + override fun bar(): In = In() +} + +fun box(): String { + return JavaClass.test(); +} diff --git a/backend.native/tests/external/codegen/blackbox/javaInterop/generics/covariantOverrideWithDeclarationSiteProjection.kt b/backend.native/tests/external/codegen/blackbox/javaInterop/generics/covariantOverrideWithDeclarationSiteProjection.kt new file mode 100644 index 00000000000..fb068efe1dc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/javaInterop/generics/covariantOverrideWithDeclarationSiteProjection.kt @@ -0,0 +1,50 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: JavaClass.java + +public class JavaClass { + + public static class C extends B { + public OutPair foo() { + return super.foo(); + } + + public In bar() { + return super.bar(); + } + } + + public static String test() { + A a = new C(); + + if (!a.foo().getX().equals("OK")) return "fail 1"; + if (!a.foo().getY().equals(123)) return "fail 2"; + + if (!a.bar().make("123").equals("123")) return "fail 3"; + + return "OK"; + } +} + +// FILE: main.kt + +class OutPair(val x: X, val y: Y) +class In { + fun make(x: Z): String = x.toString() +} + +interface A { + fun foo(): OutPair<@JvmWildcard CharSequence, @JvmSuppressWildcards(false) Number> + fun bar(): In<@JvmWildcard String> +} + +abstract class B : A { + override fun foo(): OutPair = OutPair("OK", 123) + override fun bar(): In = In() +} + +fun box(): String { + return JavaClass.test(); +} diff --git a/backend.native/tests/external/codegen/blackbox/javaInterop/generics/invariantArgumentsNoWildcard.kt b/backend.native/tests/external/codegen/blackbox/javaInterop/generics/invariantArgumentsNoWildcard.kt new file mode 100644 index 00000000000..56b2c68c129 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/javaInterop/generics/invariantArgumentsNoWildcard.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: JavaClass.java + +public class JavaClass { + public static String test() { + return MainKt.bar(MainKt.foo()); + } +} + +// FILE: main.kt + +class Pair(val x: X, val y: Y) + +class Inv(val x: T) + +fun foo(): Inv> = Inv(Pair("O", "K")) + +fun bar(inv: Inv>) = inv.x.x.toString() + inv.x.y + +fun box(): String { + return JavaClass.test(); +} diff --git a/backend.native/tests/external/codegen/blackbox/javaInterop/lambdaInstanceOf.kt b/backend.native/tests/external/codegen/blackbox/javaInterop/lambdaInstanceOf.kt new file mode 100644 index 00000000000..8c3764889d3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/javaInterop/lambdaInstanceOf.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: J.java + +import kotlin.Function; +import kotlin.jvm.functions.Function0; +import kotlin.jvm.functions.Function1; +import kotlin.jvm.functions.Function2; + +public class J { + public static String test(Function x) { + if (x instanceof Function1) return "Fail 1"; + if (x instanceof Function2) return "Fail 2"; + if (!(x instanceof Function0)) return "Fail 3"; + + return ((Function0) x).invoke(); + } +} + +// FILE: K.kt + +fun box(): String { + return J.test({ "OK" }) +} diff --git a/backend.native/tests/external/codegen/blackbox/javaInterop/notNullAssertions/extensionReceiverParameter.kt b/backend.native/tests/external/codegen/blackbox/javaInterop/notNullAssertions/extensionReceiverParameter.kt new file mode 100644 index 00000000000..344982316f4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/javaInterop/notNullAssertions/extensionReceiverParameter.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: Test.java + +public class Test { + public static String invokeFoo() { + try { + ExtensionKt.foo(null); + } + catch (IllegalArgumentException e) { + try { + ExtensionKt.getBar(null); + } + catch (IllegalArgumentException f) { + return "OK"; + } + } + + return "Fail: assertion must have been fired"; + } +} + +// FILE: extension.kt + +fun Any.foo() { } + +val Any.bar: String get() = "" + +fun box(): String { + return Test.invokeFoo() +} diff --git a/backend.native/tests/external/codegen/blackbox/javaInterop/notNullAssertions/mapPut.kt b/backend.native/tests/external/codegen/blackbox/javaInterop/notNullAssertions/mapPut.kt new file mode 100644 index 00000000000..c39287e7d2b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/javaInterop/notNullAssertions/mapPut.kt @@ -0,0 +1,10 @@ + +fun foo(k: K, v: V) { + val map = HashMap() + val old = map.put(k, v) +} + +fun box(): String { + foo("", "") + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneCallsConstructor.kt b/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneCallsConstructor.kt new file mode 100644 index 00000000000..6780c6842f8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneCallsConstructor.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +data class A(var x: Int) : Cloneable { + public override fun clone(): A = A(x) +} + +fun box(): String { + val a = A(42) + val b = a.clone() + if (b != a) return "Fail equals" + if (b === a) return "Fail identity" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneCallsSuper.kt b/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneCallsSuper.kt new file mode 100644 index 00000000000..1c2faac7156 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneCallsSuper.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +data class A(var x: Int) : Cloneable { + public override fun clone(): A = super.clone() as A +} + +fun box(): String { + val a = A(42) + val b = a.clone() + if (a != b) return "Fail equals" + if (a === b) return "Fail identity" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneCallsSuperAndModifies.kt b/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneCallsSuperAndModifies.kt new file mode 100644 index 00000000000..5671e47cb2b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneCallsSuperAndModifies.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +data class A(var x: Int) : Cloneable { + public override fun clone(): A { + val result = super.clone() as A + result.x = 239 + return result + } +} + +fun box(): String { + val a = A(42) + val b = a.clone() + if (a == b) return "Fail: $a == $b" + if (a === b) return "Fail: $a === $b" + if (b.x != 239) return "Fail: b.x = ${b.x}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneHashSet.kt b/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneHashSet.kt new file mode 100644 index 00000000000..2ec3c2d0538 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneHashSet.kt @@ -0,0 +1,12 @@ +// TARGET_BACKEND: JVM + +fun box(): String { + val a = HashSet() + a.add("live") + a.add("long") + a.add("prosper") + val b = a.clone() + if (a != b) return "Fail equals" + if (a === b) return "Fail identity" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneHierarchy.kt b/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneHierarchy.kt new file mode 100644 index 00000000000..123e036c5cf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneHierarchy.kt @@ -0,0 +1,32 @@ +// TARGET_BACKEND: JVM + +open class A : Cloneable { + public override fun clone(): A = super.clone() as A +} + +open class B(var s: String) : A() { + override fun clone(): B = super.clone() as B +} + +open class C(s: String, var l: ArrayList): B(s) { + override fun clone(): C { + val result = super.clone() as C + result.l = l.clone() as ArrayList + return result + } +} + +fun box(): String { + val l = ArrayList() + l.add(true) + + val c = C("OK", l) + val d = c.clone() + + if (c.s != d.s) return "Fail s: ${d.s}" + if (c.l != d.l) return "Fail l: ${d.l}" + if (c.l === d.l) return "Fail list identity" + if (c === d) return "Fail identity" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneableClassWithoutClone.kt b/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneableClassWithoutClone.kt new file mode 100644 index 00000000000..f15c2078344 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/javaInterop/objectMethods/cloneableClassWithoutClone.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +data class A(val s: String) : Cloneable { + fun externalClone(): A = clone() as A +} + +fun box(): String { + val a = A("OK") + val b = a.externalClone() + if (a != b) return "Fail equals" + if (a === b) return "Fail identity" + return b.s +} diff --git a/backend.native/tests/external/codegen/blackbox/jdk/arrayList.kt b/backend.native/tests/external/codegen/blackbox/jdk/arrayList.kt new file mode 100644 index 00000000000..54a5b35886e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jdk/arrayList.kt @@ -0,0 +1,12 @@ + +fun box(): String { + val a = ArrayList() + a.add(74) + a.add(75) + val i: Int = a.get(0) + val j: Int = a.get(1) + if (i != 74) return "fail 1" + if (j != 75) return "fail 2" + if (a.size != 2) return "epic fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jdk/hashMap.kt b/backend.native/tests/external/codegen/blackbox/jdk/hashMap.kt new file mode 100644 index 00000000000..3574e445e4c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jdk/hashMap.kt @@ -0,0 +1,14 @@ + +fun box(): String { + val map: MutableMap = HashMap() + map.put("a", 1) + map.put("bb", 2) + map.put("ccc", 3) + map.put("dddd", 4) + if (map.get("a") != 1) return "fail 1" + if (map.size != 4) return "fail 2" + if (map.get("eeeee") != null) return "fail 3" + if (!map.containsKey("bb")) return "fail 4" + if (map.keys.contains("ffffff")) return "fail 5" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jdk/iteratingOverHashMap.kt b/backend.native/tests/external/codegen/blackbox/jdk/iteratingOverHashMap.kt new file mode 100644 index 00000000000..c53bd2d9b6f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jdk/iteratingOverHashMap.kt @@ -0,0 +1,24 @@ + +fun box() : String { + if (!testIteratingOverMap1()) return "fail 1" + if (!testIteratingOverMap2()) return "fail 2" + return "OK" +} + +fun testIteratingOverMap1() : Boolean { + val map = HashMap() + map.put("a", 1) + for (entry in map.entries) { + entry.setValue(2) + } + return map.get("a") == 2 +} + +fun testIteratingOverMap2() : Boolean { + val map : MutableMap = HashMap() + map.put("a", 1) + for (entry in map.entries) { + entry.setValue(2) + } + return map.get("a") == 2 +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/jdk/kt1397.kt b/backend.native/tests/external/codegen/blackbox/jdk/kt1397.kt new file mode 100644 index 00000000000..17130d18c96 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jdk/kt1397.kt @@ -0,0 +1,11 @@ + +class IntArrayList(): ArrayList() { + override fun get(index: Int): Int = super.get(index) +} + +fun box(): String { + val a = IntArrayList() + a.add(1) + a[0]++ + return if (a[0] == 2) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmField/captureClassFields.kt b/backend.native/tests/external/codegen/blackbox/jvmField/captureClassFields.kt new file mode 100644 index 00000000000..be741722d3c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmField/captureClassFields.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +open class A { + @JvmField public val publicField = "1"; + @JvmField internal val internalField = "2"; + @JvmField protected val protectedField = "34"; + + fun test(): String { + return { + publicField + internalField + protectedField + }() + } +} + + +fun box(): String { + return if (A().test() == "1234") return "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmField/capturePackageFields.kt b/backend.native/tests/external/codegen/blackbox/jvmField/capturePackageFields.kt new file mode 100644 index 00000000000..17d926d01f8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmField/capturePackageFields.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@JvmField public val publicField = "1"; +@JvmField internal val internalField = "23"; + +fun test(): String { + return { + publicField + internalField + }() +} + + +fun box(): String { + return if (test() == "123") return "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmField/checkNoAccessors.kt b/backend.native/tests/external/codegen/blackbox/jvmField/checkNoAccessors.kt new file mode 100644 index 00000000000..c171a31d0b4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmField/checkNoAccessors.kt @@ -0,0 +1,40 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertFalse + +@JvmField public val field = "OK"; + +class A { + @JvmField public val field = "OK"; + + companion object { + @JvmField public val cfield = "OK"; + } +} + +object Object { + @JvmField public val field = "OK"; +} + + +fun box(): String { + var result = A().field + + checkNoAccessors(A::class.java) + checkNoAccessors(A.Companion::class.java) + checkNoAccessors(Object::class.java) + checkNoAccessors(Class.forName("CheckNoAccessorsKt")) + + return "OK" +} + +public fun checkNoAccessors(clazz: Class<*>) { + clazz.declaredMethods.forEach { + assertFalse(it.name.startsWith("get") || it.name.startsWith("set"), + "Class ${clazz.name} has accessor '${it.name}'" + ) + } +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmField/classFieldReference.kt b/backend.native/tests/external/codegen/blackbox/jvmField/classFieldReference.kt new file mode 100644 index 00000000000..9a988fb6917 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmField/classFieldReference.kt @@ -0,0 +1,45 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +package zzz +import java.lang.reflect.Field +import kotlin.reflect.KProperty1 +import kotlin.test.assertEquals + +class A(val s1: String, val s2: String) { + @JvmField public val publicField = s1; + @JvmField internal val internalField = s2; + + fun testAccessors() { + checkAccessor(A::publicField, s1, this) + checkAccessor(A::internalField, s2, this) + } +} + + +/* +// TODO: uncomment when callable references to object members are supported +class AWithCompanion { + companion object { + @JvmField public val publicField = "1"; + @JvmField internal val internalField = "2"; + + fun testAccessors() { + checkAccessor(AWithCompanion.Companion::publicField, "1", AWithCompanion.Companion) + checkAccessor(AWithCompanion.Companion::internalField, "2", AWithCompanion.Companion) + } + } +} +*/ + +fun box(): String { + A("1", "2").testAccessors() + // AWithCompanion.testAccessors() + return "OK" +} + +public fun checkAccessor(prop: KProperty1, value: R, receiver: T) { + assertEquals(prop.get(receiver), value, "Property ${prop} has wrong value") +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmField/classFieldReflection.kt b/backend.native/tests/external/codegen/blackbox/jvmField/classFieldReflection.kt new file mode 100644 index 00000000000..40afbaf376d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmField/classFieldReflection.kt @@ -0,0 +1,48 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +package zzz +import java.lang.reflect.Field +import kotlin.reflect.KProperty1 +import kotlin.test.assertEquals + + +import kotlin.reflect.KMutableProperty1 +import kotlin.test.assertEquals + +class A(val s1: String, val s2: String) { + @JvmField public var publicField = s1; + @JvmField internal var internalField = s2; + + fun testAccessors() { + checkAccessor(A::class.members.firstOrNull { it.name == "publicField" } as KMutableProperty1, s1, "3", this) + checkAccessor(A::class.members.firstOrNull { it.name == "internalField" } as KMutableProperty1, s2, "4", this) + } +} + + +class AWithCompanion { + companion object { + @JvmField public var publicField = "1"; + @JvmField internal var internalField = "2"; + + fun testAccessors() { + checkAccessor(AWithCompanion.Companion::class.members.firstOrNull { it.name == "publicField" } as KMutableProperty1, "1", "3", AWithCompanion.Companion) + checkAccessor(AWithCompanion.Companion::class.members.firstOrNull { it.name == "internalField" } as KMutableProperty1, "2", "4", AWithCompanion.Companion) + } + } +} + +fun box(): String { + A("1", "2").testAccessors() + AWithCompanion.testAccessors() + return "OK" +} + +public fun checkAccessor(prop: KMutableProperty1, value: R, newValue: R, receiver: T) { + assertEquals(prop.get(receiver), value, "Property ${prop} has wrong value") + prop.set(receiver, newValue) + assertEquals(prop.get(receiver), newValue, "Property ${prop} has wrong value") +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmField/constructorProperty.kt b/backend.native/tests/external/codegen/blackbox/jvmField/constructorProperty.kt new file mode 100644 index 00000000000..66d5f918c98 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmField/constructorProperty.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Test.java + +public class Test { + public static String invokeMethodWithPublicField() { + C c = new C("OK"); + return c.foo; + } +} + +// FILE: simple.kt + +class C(@JvmField val foo: String) { + +} + +fun box(): String { + return Test.invokeMethodWithPublicField() +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmField/publicField.kt b/backend.native/tests/external/codegen/blackbox/jvmField/publicField.kt new file mode 100644 index 00000000000..ae82c73bf6c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmField/publicField.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class A { + @JvmField public val field = "OK"; + + companion object { + @JvmField public val cfield = "OK"; + } +} + +object Object { + @JvmField public val field = "OK"; +} + + +fun box(): String { + var result = A().field + + if (result != "OK") return "fail 1: $result" + if (A.cfield != "OK") return "fail 2: ${A.cfield}" + if (Object.field != "OK") return "fail 3: ${Object.field}" + + return "OK" + +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmField/simpleMemberProperty.kt b/backend.native/tests/external/codegen/blackbox/jvmField/simpleMemberProperty.kt new file mode 100644 index 00000000000..1adf5cf3d1e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmField/simpleMemberProperty.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Test.java + +public class Test { + public static String invokeMethodWithPublicField() { + C c = new C(); + return c.foo; + } +} + +// FILE: simple.kt + +class C { + @JvmField public val foo: String = "OK" +} + +fun box(): String { + return Test.invokeMethodWithPublicField() +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmField/superCall.kt b/backend.native/tests/external/codegen/blackbox/jvmField/superCall.kt new file mode 100644 index 00000000000..e40059bd228 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmField/superCall.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +open class A { + @JvmField public val publicField = "1"; + @JvmField internal val internalField = "2"; + @JvmField protected val protectedfield = "3"; +} + + +class B : A() { + fun test(): String { + return super.publicField + super.internalField + super.protectedfield + } +} + + +fun box(): String { + return if (B().test() == "123") return "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmField/superCall2.kt b/backend.native/tests/external/codegen/blackbox/jvmField/superCall2.kt new file mode 100644 index 00000000000..184cd974061 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmField/superCall2.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +open class A { + @JvmField public val publicField = "1"; + @JvmField internal val internalField = "2"; + @JvmField protected val protectedfield = "3"; +} + +open class B : A() { + +} + +open class C : B() { + fun test(): String { + return super.publicField + super.internalField + super.protectedfield + } +} + + +fun box(): String { + return if (C().test() == "123") return "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmField/topLevelFieldReference.kt b/backend.native/tests/external/codegen/blackbox/jvmField/topLevelFieldReference.kt new file mode 100644 index 00000000000..2977f5ec59f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmField/topLevelFieldReference.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +package zzz +import java.lang.reflect.Field +import kotlin.test.assertEquals +import kotlin.reflect.KProperty0 + +@JvmField public val publicField = "1"; +@JvmField internal val internalField = "2"; + +fun testAccessors() { + val kProperty: KProperty0 = ::publicField + checkAccessor(kProperty, "1") + checkAccessor(::internalField, "2") +} + + +fun box(): String { + testAccessors() + return "OK" +} + +public fun checkAccessor(prop: KProperty0, value: R) { + assertEquals(prop.get(), value, "Property ${prop} has wrong value") +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmField/topLevelFieldReflection.kt b/backend.native/tests/external/codegen/blackbox/jvmField/topLevelFieldReflection.kt new file mode 100644 index 00000000000..c6edb440ee0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmField/topLevelFieldReflection.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +package test + +import kotlin.reflect.KMutableProperty0 +import kotlin.reflect.jvm.kotlinProperty +import kotlin.test.assertEquals + +public var publicField = "1" +internal var internalField = "2" + +fun testAccessors() { + val packageClass = Class.forName("test.TopLevelFieldReflectionKt") + packageClass.getDeclaredField("publicField").kotlinProperty + checkAccessor(packageClass.getDeclaredField("publicField").kotlinProperty as KMutableProperty0, "1", "3") + checkAccessor(packageClass.getDeclaredField("internalField").kotlinProperty as KMutableProperty0, "2", "4") +} + + +fun box(): String { + testAccessors() + return "OK" +} + +public fun < R> checkAccessor(prop: KMutableProperty0, value: R, newValue: R) { + assertEquals(prop.get(), value, "Property ${prop} has wrong value") + prop.set(newValue) + assertEquals(prop.get(), newValue, "Property ${prop} has wrong value") +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmField/visibility.kt b/backend.native/tests/external/codegen/blackbox/jvmField/visibility.kt new file mode 100644 index 00000000000..7313703b023 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmField/visibility.kt @@ -0,0 +1,71 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FULL_JDK + +import java.lang.reflect.Field +import kotlin.reflect.jvm.javaField +import kotlin.reflect.KProperty +import kotlin.test.assertNotEquals +import java.lang.reflect.Modifier + +@JvmField public val publicField = "OK"; +@JvmField internal val internalField = "OK"; + +fun testVisibilities() { + checkVisibility(::publicField.javaField!!, Modifier.PUBLIC) + checkVisibility(::internalField.javaField!!, Modifier.PUBLIC) +} + +class A { + @JvmField public val publicField = "OK"; + @JvmField internal val internalField = "OK"; + @JvmField protected val protectedfield = "OK"; + + fun testVisibilities() { + checkVisibility(A::publicField.javaField!!, Modifier.PUBLIC) + checkVisibility(A::internalField.javaField!!, Modifier.PUBLIC) + checkVisibility(A::protectedfield.javaField!!, Modifier.PROTECTED) + } +} + + +class AWithCompanion { + companion object { + @JvmField public val publicField = "OK"; + @JvmField internal val internalField = "OK"; + @JvmField protected val protectedfield = "OK"; + + operator fun get(name: String) = AWithCompanion.Companion::class.members.single { it.name == name } as KProperty<*> + + fun testVisibilities() { + checkVisibility(this["publicField"].javaField!!, Modifier.PUBLIC) + checkVisibility(this["internalField"].javaField!!, Modifier.PUBLIC) + checkVisibility(this["protectedfield"].javaField!!, Modifier.PROTECTED) + } + } +} + +object Object { + @JvmField public val publicField = "OK"; + @JvmField internal val internalField = "OK"; + + operator fun get(name: String) = Object::class.members.single { it.name == name } as KProperty<*> + + fun testVisibilities() { + checkVisibility(this["publicField"].javaField!!, Modifier.PUBLIC) + checkVisibility(this["internalField"].javaField!!, Modifier.PUBLIC) + } +} + +fun box(): String { + A().testVisibilities() + AWithCompanion.testVisibilities() + Object.testVisibilities() + return "OK" +} + +public fun checkVisibility(field: Field, visibility: Int) { + assertNotEquals(field.modifiers and visibility, 0, "Field ${field} has wrong visibility") +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmField/writeFieldReference.kt b/backend.native/tests/external/codegen/blackbox/jvmField/writeFieldReference.kt new file mode 100644 index 00000000000..651cccee665 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmField/writeFieldReference.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +package zzz +import kotlin.reflect.KMutableProperty1 +import kotlin.test.assertEquals + +class A(val s1: String, val s2: String) { + @JvmField public var publicField = s1; + @JvmField internal var internalField = s2; + + fun testAccessors() { + val kMutableProperty: KMutableProperty1 = A::publicField + checkAccessor(kMutableProperty, s1, "3", this) + checkAccessor(A::internalField, s2, "4", this) + } +} + +fun box(): String { + A("1", "2").testAccessors() + return "OK" +} + +public fun checkAccessor(prop: KMutableProperty1, value: R, newValue: R, receiver: T) { + assertEquals(prop.get(receiver), value, "Property ${prop} has wrong value") + prop.set(receiver, newValue) + assertEquals(prop.get(receiver), newValue, "Property ${prop} has wrong value") +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmName/callableReference.kt b/backend.native/tests/external/codegen/blackbox/jvmName/callableReference.kt new file mode 100644 index 00000000000..c53653a6686 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmName/callableReference.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@JvmName("bar") +fun foo() = "foo" + +fun box(): String { + val f = (::foo)() + if (f != "foo") return "Fail: $f" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmName/clashingErasure.kt b/backend.native/tests/external/codegen/blackbox/jvmName/clashingErasure.kt new file mode 100644 index 00000000000..7605893e6b3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmName/clashingErasure.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun List.foo() = "foo" + +@JvmName("fooInt") +fun List.foo() = "fooInt" + +fun box(): String { + val strings = listOf("", "").foo() + if (strings != "foo") return "Fail: $strings" + + val ints = listOf(1, 2).foo() + if (ints != "fooInt") return "Fail: $ints" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmName/classMembers.kt b/backend.native/tests/external/codegen/blackbox/jvmName/classMembers.kt new file mode 100644 index 00000000000..924e913db4b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmName/classMembers.kt @@ -0,0 +1,121 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// See: +// http://kotlinlang.org/docs/reference/java-interop.html#handling-signature-clashes-with-platformname +// https://youtrack.jetbrains.com/issue/KT-5524 + +val strs = listOf("abc", "def") +val ints = listOf(1, 2, 3) + +class C { + // Instance methods + + @JvmName("instMethodStr") + fun instMethod(list: List): String = "instMethodStr" + + @JvmName("instMethodInt") + fun instMethod(list: List): String = "instMethodInt" + + // Properties + + var rwProperty: Int + @JvmName("get_rwProperty") + get() = 123 + @JvmName("set_rwProperty") + set(v) {} + + var rwValue = 111 + + fun getRwProperty(): Int = rwValue + + fun setRwProperty(v: Int) { + rwValue = v + } + + // Extension methods + + class Inner + + @JvmName("extMethodWithGenericParamStr") + fun Inner.extMethodWithGenericParam(list: List): String = "extMethodWithGenericParamStr" + + @JvmName("extMethodWithGenericParamInt") + fun Inner.extMethodWithGenericParam(list: List): String = "extMethodWithGenericParamInt" + + // This is already covered by extMethodWithGenericParam(), but might be relevant for a platform + // with extension method code generation strategy different from Java 6. + + @JvmName("extMethodWithGenericReceiverStr") + fun List.extMethodWithGenericReceiver(): String = "extMethodWithGenericReceiverStr" + + @JvmName("extMethodWithGenericReceiverInt") + fun List.extMethodWithGenericReceiver(): String = "extMethodWithGenericReceiverInt" + + // Extension method vs instance method + + @JvmName("ambigMethod1") + fun ambigMethod(str: String): String = "ambigMethod1" + + @JvmName("ambigMethod2") + fun String.ambigMethod(): String = "ambigMethod2" + +} + +fun box(): String { + val c = C() + + // Instance methods: + // method signatures with erased types SHOULD NOT clash + + val test1 = c.instMethod(strs) + if (test1 != "instMethodStr") return "Fail: c.instMethod(strs)==$test1" + + val test2 = c.instMethod(ints) + if (test2 != "instMethodInt") return "Fail: c.instMethod(ints)==$test2" + + // Properties: + // property accessors SHOULD NOT clash with class methods + + val test3 = c.rwProperty + if (test3 != 123) return "Fail: c.rwProperty==$test3" + + val test3a = c.getRwProperty() + if (test3a != 111) return "Fail: c.getRwProperty()==$test3a" + + c.setRwProperty(444) + val test3b = c.rwProperty + if (test3b != 123) return "Fail: c.rwProperty==$test3b after c.setRwProperty(1234)" + val test3c = c.getRwProperty() + if (test3c != 444) return "Fail: c.getRwProperty()==$test3c after c.setRwProperty(1234)" + + // Extension methods: + // method signatures with erased types SHOULD NOT clash + + val test4 = with(c) { C.Inner().extMethodWithGenericParam(strs) } + if (test4 != "extMethodWithGenericParamStr") return "Fail: with(c) { C.Inner().extMethodWithGenericParam(strs) }==$test4" + + val test5 = with(c) { C.Inner().extMethodWithGenericParam(ints) } + if (test5 != "extMethodWithGenericParamInt") return "Fail: with(c) { C.Inner().extMethodWithGenericParam(ints) }==$test5" + + val test6 = with(c) { strs.extMethodWithGenericReceiver() } + if (test6 != "extMethodWithGenericReceiverStr") return "Fail: with(c) { strs.extMethodWithGenericReceiver() }==$test6" + + val test7 = with(c) { ints.extMethodWithGenericReceiver() } + if (test7 != "extMethodWithGenericReceiverInt") return "Fail: with(c) { ints.extMethodWithGenericReceiver() }==$test7" + + // Extension method SHOULD NOT clash with instance method with the same Java signature. + + val str = "abc" + + val test8 = with(c) { ambigMethod(str) } + if (test8 != "ambigMethod1") return "Fail: with(c) { ambigMethod(str) }==$test8" + + val test9 = with(c) { str.ambigMethod() } + if (test9 != "ambigMethod2") return "Fail: with(c) { str.ambigMethod() }==$test9" + + // Everything is fine. + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmName/fakeJvmNameInJava.kt b/backend.native/tests/external/codegen/blackbox/jvmName/fakeJvmNameInJava.kt new file mode 100644 index 00000000000..cb01a158914 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmName/fakeJvmNameInJava.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: FakePlatformName.java + +import kotlin.jvm.JvmName; + +public class FakePlatformName { + @JvmName(name = "fake") + public String foo() { + return "foo"; + } + + public String fake() { + return "fake"; + } +} + +// FILE: FakePlatformName.kt + +fun box(): String { + val test1 = FakePlatformName().foo() + if (test1 != "foo") return "Failed: FakePlatformName().foo()==$test1" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmName/fileFacades/differentFiles.kt b/backend.native/tests/external/codegen/blackbox/jvmName/fileFacades/differentFiles.kt new file mode 100644 index 00000000000..2c8052a7515 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmName/fileFacades/differentFiles.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Baz.java + +public class Baz { + public static String baz() { + return Foo.foo() + Bar.bar(); + } +} + +// FILE: bar.kt + +@file:JvmName("Bar") +public fun bar(): String = "K" + +// FILE: foo.kt + +@file:JvmName("Foo") +public fun foo(): String = "O" + +// FILE: test.kt + +fun box(): String = Baz.baz() diff --git a/backend.native/tests/external/codegen/blackbox/jvmName/fileFacades/javaAnnotationOnFileFacade.kt b/backend.native/tests/external/codegen/blackbox/jvmName/fileFacades/javaAnnotationOnFileFacade.kt new file mode 100644 index 00000000000..1129e381e0c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmName/fileFacades/javaAnnotationOnFileFacade.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: StringHolder.java + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface StringHolder { + public String value(); +} + +// FILE: fileFacade.kt + +@file:StringHolder("OK") + +fun box(): String = + Class.forName("FileFacadeKt").getAnnotation(StringHolder::class.java)?.value ?: "null" diff --git a/backend.native/tests/external/codegen/blackbox/jvmName/fileFacades/simple.kt b/backend.native/tests/external/codegen/blackbox/jvmName/fileFacades/simple.kt new file mode 100644 index 00000000000..b13c563bb7e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmName/fileFacades/simple.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Bar.java + +public class Bar { + public static String bar() { + return Foo.foo(); + } +} + +// FILE: foo.kt + +@file:JvmName("Foo") +public fun foo(): String = "OK" + +// FILE: simple.kt + +fun box(): String = Bar.bar() diff --git a/backend.native/tests/external/codegen/blackbox/jvmName/functionName.kt b/backend.native/tests/external/codegen/blackbox/jvmName/functionName.kt new file mode 100644 index 00000000000..931c86664a2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmName/functionName.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@JvmName("bar") +fun foo() = "foo" + +fun box(): String { + val f = foo() + if (f != "foo") return "Fail: $f" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmName/multifileClass.kt b/backend.native/tests/external/codegen/blackbox/jvmName/multifileClass.kt new file mode 100644 index 00000000000..166e221662c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmName/multifileClass.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@file:JvmName("Test") +@file:JvmMultifileClass +package test + +fun foo(): String = bar() +fun bar(): String = qux() +fun qux(): String = "OK" + +fun box(): String = foo() diff --git a/backend.native/tests/external/codegen/blackbox/jvmName/multifileClassWithLocalClass.kt b/backend.native/tests/external/codegen/blackbox/jvmName/multifileClassWithLocalClass.kt new file mode 100644 index 00000000000..bab369e1ca6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmName/multifileClassWithLocalClass.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@file:JvmName("Test") +@file:JvmMultifileClass +package test + +fun foo(): String = bar() +fun bar(): String { + class Local(val x: String) + return Local("OK").x +} + +fun box(): String = foo() diff --git a/backend.native/tests/external/codegen/blackbox/jvmName/multifileClassWithLocalGeneric.kt b/backend.native/tests/external/codegen/blackbox/jvmName/multifileClassWithLocalGeneric.kt new file mode 100644 index 00000000000..1bed0ec5cc0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmName/multifileClassWithLocalGeneric.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@file:JvmName("Test") +@file:JvmMultifileClass +package test + +fun foo(): String = bar() +fun bar(): String { + open class LocalGeneric(val x: T) + class Derived(x: String) : LocalGeneric(x) + fun LocalGeneric.extFun() = this + fun localFun(x: LocalGeneric) = x + class Local3 { + fun method(x: LocalGeneric) = x.x + } + return Local3().method(localFun(Derived("OK")).extFun()) +} + +fun box(): String = foo() diff --git a/backend.native/tests/external/codegen/blackbox/jvmName/propertyAccessorsUseSite.kt b/backend.native/tests/external/codegen/blackbox/jvmName/propertyAccessorsUseSite.kt new file mode 100644 index 00000000000..18f7752943b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmName/propertyAccessorsUseSite.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +class TestIt { + @get:JvmName("getIsFries") + @set:JvmName("setIsFries") + var isFries: Boolean = true + + @get:JvmName("getIsUpdateable") + @set:JvmName("setIsUpdateable") + var isUpdateable: Boolean by Delegate +} + +object Delegate { + operator fun getValue(thiz: Any?, metadata: Any?) = true + operator fun setValue(thiz: Any?, metadata: Any?, value: Boolean) {} +} + +fun box(): String { + assertEquals( + listOf("getIsFries", "getIsUpdateable", "setIsFries", "setIsUpdateable"), + TestIt::class.java.declaredMethods.map { it.name }.sorted() + ) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmName/propertyName.kt b/backend.native/tests/external/codegen/blackbox/jvmName/propertyName.kt new file mode 100644 index 00000000000..a0285a5ac09 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmName/propertyName.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +var v: Int = 1 + @JvmName("vget") + get + @JvmName("vset") + set + +fun box(): String { + v += 1 + if (v != 2) return "Fail: $v" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmName/renamedFileClass.kt b/backend.native/tests/external/codegen/blackbox/jvmName/renamedFileClass.kt new file mode 100644 index 00000000000..d40e19ee331 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmName/renamedFileClass.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@file:JvmName("Util") +package test + +fun foo(): String = bar() +fun bar(): String = qux() +fun qux(): String = "OK" + +fun box(): String = foo() diff --git a/backend.native/tests/external/codegen/blackbox/jvmOverloads/companionObject.kt b/backend.native/tests/external/codegen/blackbox/jvmOverloads/companionObject.kt new file mode 100644 index 00000000000..842a2deff08 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmOverloads/companionObject.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class C { + companion object { + @JvmStatic @kotlin.jvm.JvmOverloads public fun foo(o: String, k: String = "K"): String { + return o + k + } + } +} + +fun box(): String { + val m = C::class.java.getMethod("foo", String::class.java) + return m.invoke(null, "O") as String +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmOverloads/defaultsNotAtEnd.kt b/backend.native/tests/external/codegen/blackbox/jvmOverloads/defaultsNotAtEnd.kt new file mode 100644 index 00000000000..b5643b1daab --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmOverloads/defaultsNotAtEnd.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class C { + @kotlin.jvm.JvmOverloads public fun foo(o: String = "O", i1: Int, k: String = "K", i2: Int): String { + return o + k + } +} + +fun box(): String { + val c = C() + val m = c.javaClass.getMethod("foo", Int::class.java, Int::class.java) + return m.invoke(c, 1, 2) as String +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmOverloads/doubleParameters.kt b/backend.native/tests/external/codegen/blackbox/jvmOverloads/doubleParameters.kt new file mode 100644 index 00000000000..7544f76c9f1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmOverloads/doubleParameters.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class C { + @kotlin.jvm.JvmOverloads public fun foo(d1: Double, d2: Double, status: String = "OK"): String { + return if (d1 + d2 == 3.0) status else "fail" + } +} + +fun box(): String { + val c = C() + val m = c.javaClass.getMethod("foo", Double::class.java, Double::class.java) + return m.invoke(c, 1.0, 2.0) as String +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmOverloads/extensionMethod.kt b/backend.native/tests/external/codegen/blackbox/jvmOverloads/extensionMethod.kt new file mode 100644 index 00000000000..14c8658c299 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmOverloads/extensionMethod.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class C { +} + +@kotlin.jvm.JvmOverloads fun C.foo(o: String, k: String = "K"): String { + return o + k +} + +fun box(): String { + val m = C::class.java.getClassLoader().loadClass("ExtensionMethodKt").getMethod("foo", C::class.java, String::class.java) + return m.invoke(null, C(), "O") as String +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmOverloads/generics.kt b/backend.native/tests/external/codegen/blackbox/jvmOverloads/generics.kt new file mode 100644 index 00000000000..88f6cc90649 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmOverloads/generics.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Test.java + +public class Test { + public static String invokeMethodWithOverloads() { + C c = new C(); + return c.foo("O"); + } +} + +// FILE: generics.kt + +class C { + @kotlin.jvm.JvmOverloads public fun foo(o: T, k: String = "K"): String = o.toString() + k +} + +fun box(): String { + return Test.invokeMethodWithOverloads() +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmOverloads/innerClass.kt b/backend.native/tests/external/codegen/blackbox/jvmOverloads/innerClass.kt new file mode 100644 index 00000000000..22e736d4d58 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmOverloads/innerClass.kt @@ -0,0 +1,15 @@ +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class Outer { + inner class Inner @JvmOverloads constructor(val s1: String, val s2: String = "OK") { + + } +} + +fun box(): String { + val outer = Outer() + val c = (Outer.Inner::class.java.getConstructor(Outer::class.java, String::class.java).newInstance(outer, "shazam")) + return c.s2 +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmOverloads/multipleDefaultParameters.kt b/backend.native/tests/external/codegen/blackbox/jvmOverloads/multipleDefaultParameters.kt new file mode 100644 index 00000000000..6d3c1f720e6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmOverloads/multipleDefaultParameters.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class C { + @kotlin.jvm.JvmOverloads public fun foo(o: String = "O", k: String = "K"): String { + return o + k + } +} + +fun box(): String { + val c = C() + val m = c.javaClass.getMethod("foo") + return m.invoke(c) as String +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmOverloads/nonDefaultParameter.kt b/backend.native/tests/external/codegen/blackbox/jvmOverloads/nonDefaultParameter.kt new file mode 100644 index 00000000000..11f3d564674 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmOverloads/nonDefaultParameter.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class C { + @kotlin.jvm.JvmOverloads public fun foo(o: String, k: String = "K"): String { + return o + k + } +} + +fun box(): String { + val c = C() + val m = c.javaClass.getMethod("foo", String::class.java) + return m.invoke(c, "O") as String +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmOverloads/primaryConstructor.kt b/backend.native/tests/external/codegen/blackbox/jvmOverloads/primaryConstructor.kt new file mode 100644 index 00000000000..cc74a22f3bd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmOverloads/primaryConstructor.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class C @kotlin.jvm.JvmOverloads constructor(s1: String, s2: String = "K") { + public val status: String = s1 + s2 +} + +fun box(): String { + val c = (C::class.java.getConstructor(String::class.java).newInstance("O")) + return c.status +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmOverloads/privateClass.kt b/backend.native/tests/external/codegen/blackbox/jvmOverloads/privateClass.kt new file mode 100644 index 00000000000..2c473204597 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmOverloads/privateClass.kt @@ -0,0 +1,10 @@ +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +private data class C(val status: String = "OK") + +fun box(): String { + val c = (C::class.java.getConstructor().newInstance()) + return c.status +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmOverloads/secondaryConstructor.kt b/backend.native/tests/external/codegen/blackbox/jvmOverloads/secondaryConstructor.kt new file mode 100644 index 00000000000..28461330abb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmOverloads/secondaryConstructor.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class C(val i: Int) { + var status = "fail" + + @kotlin.jvm.JvmOverloads constructor(o: String, k: String = "K"): this(-1) { + status = o + k + } +} + +fun box(): String { + val c = (C::class.java.getConstructor(String::class.java).newInstance("O")) + return c.status +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmOverloads/simple.kt b/backend.native/tests/external/codegen/blackbox/jvmOverloads/simple.kt new file mode 100644 index 00000000000..b11dc787dd7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmOverloads/simple.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class C { + @kotlin.jvm.JvmOverloads public fun foo(s: String = "OK"): String { + return s + } +} + +fun box(): String { + val c = C() + val m = c.javaClass.getMethod("foo") + return m.invoke(c) as String +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmOverloads/simpleJavaCall.kt b/backend.native/tests/external/codegen/blackbox/jvmOverloads/simpleJavaCall.kt new file mode 100644 index 00000000000..cf7edad65ac --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmOverloads/simpleJavaCall.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Test.java + +public class Test { + public static String invokeMethodWithOverloads() { + C c = new C(); + return c.foo(); + } +} + +// FILE: simple.kt + +class C { + @kotlin.jvm.JvmOverloads public fun foo(o: String = "O", k: String = "K"): String = o + k +} + +fun box(): String { + return Test.invokeMethodWithOverloads() +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmOverloads/varargs.kt b/backend.native/tests/external/codegen/blackbox/jvmOverloads/varargs.kt new file mode 100644 index 00000000000..1ca99e71284 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmOverloads/varargs.kt @@ -0,0 +1,16 @@ +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class C { + @JvmOverloads + fun foo(bar: Int = 0, vararg status: String) { + + } +} + +fun box(): String { + val c = C() + val m = c.javaClass.getMethod("foo", Array::class.java) + return if (m.isVarArgs) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/annotations.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/annotations.kt new file mode 100644 index 00000000000..3fe90d7a0e2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/annotations.kt @@ -0,0 +1,61 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Test.java + +import java.lang.annotation.Annotation; + +class Test { + + public static String test1() throws NoSuchMethodException { + Annotation[] test1s = A.class.getMethod("test1").getAnnotations(); + for (Annotation test : test1s) { + String name = test.toString(); + if (name.contains("testAnnotation")) { + return "OK"; + } + } + return "fail"; + } + + public static String test2() throws NoSuchMethodException { + Annotation[] test2s = B.class.getMethod("test1").getAnnotations(); + for (Annotation test : test2s) { + String name = test.toString(); + if (name.contains("testAnnotation")) { + return "OK"; + } + } + return "fail"; + } + +} + +// FILE: test.kt + +@Retention(AnnotationRetention.RUNTIME) +annotation class testAnnotation + +class A { + + companion object { + val b: String = "OK" + + @JvmStatic @testAnnotation fun test1() = b + } +} + +object B { + val b: String = "OK" + + @JvmStatic @testAnnotation fun test1() = b +} + +fun box(): String { + if (Test.test1() != "OK") return "fail 1" + + if (Test.test2() != "OK") return "fail 2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/closure.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/closure.kt new file mode 100644 index 00000000000..05998f701a7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/closure.kt @@ -0,0 +1,51 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +object A { + + val b: String = "OK" + + @JvmStatic val c: String = "OK" + + @JvmStatic fun test1() : String { + return {b}() + } + + @JvmStatic fun test2() : String { + return {test1()}() + } + + fun test3(): String { + return {"1".test5()}() + } + + @JvmStatic fun test4(): String { + return {"1".test5()}() + } + + @JvmStatic fun String.test5() : String { + return {this + b}() + } + + fun test6(): String { + return {c}() + } +} + +fun box(): String { + if (A.test1() != "OK") return "fail 1" + + if (A.test2() != "OK") return "fail 2" + + if (A.test3() != "1OK") return "fail 3" + + if (A.test4() != "1OK") return "fail 4" + + if (with(A) {"1".test5()} != "1OK") return "fail 5" + + if (A.test6() != "OK") return "fail 6" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/companionObject.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/companionObject.kt new file mode 100644 index 00000000000..d5bd0c41445 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/companionObject.kt @@ -0,0 +1,54 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Test.java + +class Test { + + public static String test1() { + return A.test1(); + } + + public static String test2() { + return A.test2(); + } + + public static String test3() { + return A.test3("JAVA"); + } + + public static String test4() { + return A.getC(); + } + +} + +// FILE: simpleCompanionObject.kt + +class A { + + companion object { + val b: String = "OK" + + @JvmStatic val c: String = "OK" + + @JvmStatic fun test1() = b + + @JvmStatic fun test2() = b + + @JvmStatic fun String.test3() = this + b + } +} + +fun box(): String { + if (Test.test1() != "OK") return "fail 1" + + if (Test.test2() != "OK") return "fail 2" + + if (Test.test3() != "JAVAOK") return "fail 3" + + if (Test.test4() != "OK") return "fail 4" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/convention.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/convention.kt new file mode 100644 index 00000000000..f586013cf39 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/convention.kt @@ -0,0 +1,36 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class B(var s: Int = 0) { + +} + +object A { + + fun test1(v: B) { + v += B(1000) + } + + @JvmStatic operator fun B.plusAssign(b: B) { + this.s += b.s + } +} + +fun box(): String { + + val b1 = B(11) + + with(A) { + b1 += B(1000) + } + + if (b1.s != 1011) return "fail 1" + + val b = B(11) + A.test1(b) + if (b.s != 1011) return "fail 2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/default.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/default.kt new file mode 100644 index 00000000000..3e2b82f62a7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/default.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +object A { + + @JvmStatic fun test(b: String = "OK") : String { + return b + } +} + +fun box(): String { + + if (A.test() != "OK") return "fail 1" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/enumCompanion.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/enumCompanion.kt new file mode 100644 index 00000000000..9c635ea32f8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/enumCompanion.kt @@ -0,0 +1,46 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Test.java + +class Test { + public static String foo() { + return A.foo; + } + + public static String constBar() { + return A.constBar; + } + + public static String getBar() { + return A.getBar(); + } + + public static String baz() { + return A.baz(); + } +} + +// FILE: enumCompanionObject.kt + +enum class A { + ; + companion object { + @JvmField val foo: String = "OK" + + const val constBar: String = "OK" + + @JvmStatic val bar: String = "OK" + + @JvmStatic fun baz() = foo + } +} + +fun box(): String { + if (Test.foo() != "OK") return "Fail foo" + if (Test.constBar() != "OK") return "Fail bar" + if (Test.getBar() != "OK") return "Fail getBar" + if (Test.baz() != "OK") return "Fail baz" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/explicitObject.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/explicitObject.kt new file mode 100644 index 00000000000..641dfc80e98 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/explicitObject.kt @@ -0,0 +1,37 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +object AX { + + @JvmStatic val c: String = "OK" + + @JvmStatic fun aStatic(): String { + return AX.b() + } + + fun aNonStatic(): String { + return AX.b() + } + + @JvmStatic fun b(): String { + return "OK" + } + + fun getProperty(): String { + return AX.c + } + +} + +fun box() : String { + + if (AX.aStatic() != "OK") return "fail 1" + + if (AX.aNonStatic() != "OK") return "fail 2" + + if (AX.getProperty() != "OK") return "fail 3" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/funAccess.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/funAccess.kt new file mode 100644 index 00000000000..7601d2da506 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/funAccess.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +var holder = "" + +fun getA(): A { + holder += "OK" + return A +} + +object A { + @JvmStatic fun a(): String { + return holder + } +} + +fun box(): String { + return getA().a() +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/importStaticMemberFromObject.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/importStaticMemberFromObject.kt new file mode 100644 index 00000000000..7311331ef0f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/importStaticMemberFromObject.kt @@ -0,0 +1,35 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import O.p +import O.f +import C.Companion.p1 +import C.Companion.f1 + +object O { + @JvmStatic + fun f(): Int = 3 + + @JvmStatic + val p: Int = 6 +} + +class C { + companion object { + @JvmStatic + fun f1(): Int = 3 + + @JvmStatic + val p1: Int = 6 + } + +} + +fun box(): String { + if (p + f() != 9) return "fail" + if (p1 + f1() != 9) return "fail2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/inline.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/inline.kt new file mode 100644 index 00000000000..4977ac1fdca --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/inline.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +object A { + + @JvmStatic inline fun test(b: String = "OK") : String { + return b + } +} + +fun box(): String { + + if (A.test() != "OK") return "fail 1" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/inlinePropertyAccessors.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/inlinePropertyAccessors.kt new file mode 100644 index 00000000000..b4c219999f6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/inlinePropertyAccessors.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +var result = "fail 1" +object Foo { + @JvmStatic + private val a = "OK" + + fun foo() = run { result = a } +} + +fun box(): String { + Foo.foo() + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/kt9897_static.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/kt9897_static.kt new file mode 100644 index 00000000000..a3ca2723748 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/kt9897_static.kt @@ -0,0 +1,46 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +object Test { + var z = "0" + var l = 0L + + fun changeObject(): String { + "1".someProperty += 1 + return z + } + + fun changeLong(): Long { + 2L.someProperty -= 1 + return l + } + + @JvmStatic var String.someProperty: Int + get() { + return this.length + } + set(left) { + z += this + left + } + + @JvmStatic var Long.someProperty: Long + get() { + return l + } + set(left) { + l += this + left + } + +} + +fun box(): String { + val changeObject = Test.changeObject() + if (changeObject != "012") return "fail 1: $changeObject" + + val changeLong = Test.changeLong() + if (changeLong != 1L) return "fail 1: $changeLong" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/object.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/object.kt new file mode 100644 index 00000000000..98ce03c845a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/object.kt @@ -0,0 +1,52 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Test.java + +class Test { + + public static String test1() { + return A.test1(); + } + + public static String test2() { + return A.test2(); + } + + public static String test3() { + return A.test3("JAVA"); + } + + public static String test4() { + return A.getC(); + } + +} + +// FILE: simpleObject.kt + +object A { + + val b: String = "OK" + + @JvmStatic val c: String = "OK" + + @JvmStatic fun test1() = b + + @JvmStatic fun test2() = b + + @JvmStatic fun String.test3() = this + b +} + +fun box(): String { + if (Test.test1() != "OK") return "fail 1" + + if (Test.test2() != "OK") return "fail 2" + + if (Test.test3() != "JAVAOK") return "fail 3" + + if (Test.test4() != "OK") return "fail 4" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/postfixInc.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/postfixInc.kt new file mode 100644 index 00000000000..202cd0b0d06 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/postfixInc.kt @@ -0,0 +1,50 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +object A { + + @JvmStatic var a: Int = 1 + + var b: Int = 1 + @JvmStatic get + + var c: Int = 1 + @JvmStatic set + +} + +var holder = "" +fun getA(): A { + holder += "getA()" + return A +} + + +fun box(): String { + + var p = A.a++ + if (p != 1 || A.a != 2) return "fail 1" + + p = A.b++ + if (p != 1 || A.b != 2) return "fail 2" + + p = A.c++ + if (p != 1 || A.c != 2) return "fail 3" + + + p = getA().a++ + if (p != 2 || A.a != 3 || holder != "getA()") return "fail 4: $holder" + holder = "" + + p = getA().b++ + if (p != 2 || A.b != 3 || holder != "getA()") return "fail 5: $holder" + holder = "" + + p = getA().c++ + if (p != 2 || A.c != 3 || holder != "getA()") return "fail 6: $holder" + holder = "" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/prefixInc.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/prefixInc.kt new file mode 100644 index 00000000000..f81a1467b48 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/prefixInc.kt @@ -0,0 +1,50 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +object A { + + @JvmStatic var a: Int = 1 + + var b: Int = 1 + @JvmStatic get + + var c: Int = 1 + @JvmStatic set + +} + +var holder = "" +fun getA(): A { + holder += "getA()" + return A +} + + +fun box(): String { + + var p = ++A.a + if (p != 2 || A.a != 2) return "fail 1" + + p = ++A.b + if (p != 2 || A.b != 2) return "fail 2" + + p = ++A.c + if (p != 2 || A.c != 2) return "fail 3" + + + p = ++getA().a + if (p != 3 || A.a != 3 || holder != "getA()") return "fail 4: $holder" + holder = "" + + p = ++getA().b + if (p != 3 || A.b != 3 || holder != "getA()") return "fail 5: $holder" + holder = "" + + p = ++getA().c + if (p != 3 || A.c != 3 || holder != "getA()") return "fail 6: $holder" + holder = "" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/privateMethod.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/privateMethod.kt new file mode 100644 index 00000000000..a993a425f4a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/privateMethod.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +object A { + + private @JvmStatic fun a(): String { + return "OK" + } + + object Z { + val p = a() + } +} + +fun box(): String { + return A.Z.p +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/privateSetter.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/privateSetter.kt new file mode 100644 index 00000000000..50c6d83a13e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/privateSetter.kt @@ -0,0 +1,27 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: JavaClass.java +class JavaClass { + + + public static String test() + { + return TestApp.getValue(); + } +} + +// FILE: Kotlin.kt +open class TestApp { + companion object { + @JvmStatic + var value: String = "OK" + private set + } +} + + +fun box(): String { + return JavaClass.test() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/propertyAccess.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/propertyAccess.kt new file mode 100644 index 00000000000..3ccb556b423 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/propertyAccess.kt @@ -0,0 +1,50 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +var holder = "" + +fun getA(): A { + holder += "getA()" + return A +} + +object A { + + @JvmStatic var a: Int = 1 + + var b: Int = 1 + @JvmStatic get + + var c: Int = 1 + @JvmStatic set + +} + + +fun box(): String { + + if (getA().a != 1 || holder != "getA()") return "fail 1: $holder" + holder = "" + + if (getA().b != 1 || holder != "getA()") return "fail 2: $holder" + holder = "" + + if (getA().c != 1 || holder != "getA()") return "fail 3: $holder" + holder = "" + + getA().a = 2 + if (getA().a != 2 || holder != "getA()getA()") return "fail 1: $holder" + holder = "" + + getA().b = 2 + if (getA().b != 2 || holder != "getA()getA()") return "fail 2: $holder" + holder = "" + + getA().c = 2 + if (getA().c != 2 || holder != "getA()getA()") return "fail 3: $holder" + holder = "" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/propertyAccessorsCompanion.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/propertyAccessorsCompanion.kt new file mode 100644 index 00000000000..9ce9cd9e1fb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/propertyAccessorsCompanion.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +var result = "fail 2" +class Foo { + val b = { a } + val c = Runnable { result = a } + + companion object { + @JvmStatic + private val a = "OK" + } +} + +fun box(): String { + if (Foo().b() != "OK") return "fail 1" + + Foo().c.run() + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/propertyAccessorsObject.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/propertyAccessorsObject.kt new file mode 100644 index 00000000000..6e3df7272ed --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/propertyAccessorsObject.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +var result = "fail 2" +object Foo { + @JvmStatic + private val a = "OK" + + val b = { a } + val c = Runnable { result = a } +} + +fun box(): String { + if (Foo.b() != "OK") return "fail 1" + + Foo.c.run() + + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/propertyAsDefault.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/propertyAsDefault.kt new file mode 100644 index 00000000000..123d32ff19d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/propertyAsDefault.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +object X { + @JvmStatic val x = "OK" + + fun fn(value : String = x): String = value +} + +fun box(): String { + return X.fn() +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/simple.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/simple.kt new file mode 100644 index 00000000000..535955271a5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/simple.kt @@ -0,0 +1,47 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +object A { + + val b: String = "OK" + + @JvmStatic val c: String = "OK" + + @JvmStatic fun test1() : String { + return b + } + + @JvmStatic fun test2() : String { + return test1() + } + + fun test3(): String { + return "1".test5() + } + + @JvmStatic fun test4(): String { + return "1".test5() + } + + @JvmStatic fun String.test5() : String { + return this + b + } +} + +fun box(): String { + if (A.test1() != "OK") return "fail 1" + + if (A.test2() != "OK") return "fail 2" + + if (A.test3() != "1OK") return "fail 3" + + if (A.test4() != "1OK") return "fail 4" + + if (with(A) {"1".test5()} != "1OK") return "fail 5" + + if (A.c != "OK") return "fail 6" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/jvmStatic/syntheticAccessor.kt b/backend.native/tests/external/codegen/blackbox/jvmStatic/syntheticAccessor.kt new file mode 100644 index 00000000000..76e27b7f63f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/jvmStatic/syntheticAccessor.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class C { + companion object { + private @JvmStatic fun foo(): String { + return "OK" + } + } + + fun bar(): String { + return foo() + } +} + +fun box(): String { + return C().bar() +} diff --git a/backend.native/tests/external/codegen/blackbox/labels/labeledDeclarations.kt b/backend.native/tests/external/codegen/blackbox/labels/labeledDeclarations.kt new file mode 100644 index 00000000000..5b407c979fb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/labels/labeledDeclarations.kt @@ -0,0 +1,16 @@ +data class A(val a: Int, val b: Int) + +fun box() : String +{ + a@ val x = 1 + b@ fun a() = 2 + c@ val (z, z2) = A(1, 2) + + if (x != 1) return "fail 1" + + if (a() != 2) return "fail 2" + + if (z != 1 || z2 != 2) return "fail 3" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/labels/propertyAccessor.kt b/backend.native/tests/external/codegen/blackbox/labels/propertyAccessor.kt new file mode 100644 index 00000000000..b9973e82ddc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/labels/propertyAccessor.kt @@ -0,0 +1,11 @@ +val Int.getter: Int + get() { + return this@getter + } + +fun box(): String { + val i = 1 + if (i.getter != 1) return "getter failed" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/labels/propertyAccessorFunctionLiteral.kt b/backend.native/tests/external/codegen/blackbox/labels/propertyAccessorFunctionLiteral.kt new file mode 100644 index 00000000000..6d26e930ed2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/labels/propertyAccessorFunctionLiteral.kt @@ -0,0 +1,13 @@ +val Int.getter: Int + get() { + return { + this@getter + }.invoke() + } + +fun box(): String { + val i = 1 + if (i.getter != 1) return "getter failed" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/labels/propertyAccessorInnerExtensionFun.kt b/backend.native/tests/external/codegen/blackbox/labels/propertyAccessorInnerExtensionFun.kt new file mode 100644 index 00000000000..1a57fc6e039 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/labels/propertyAccessorInnerExtensionFun.kt @@ -0,0 +1,28 @@ +val Int.getter: Int + get() { + val extFun: Int.() -> Int = { + this@getter + } + return this@getter.extFun() + } + + +var Int.setter: Int + get() = 1 + set(i: Int) { + val extFun: Int.() -> Int = { + this@setter + } + this@setter.extFun() + } + + +fun box(): String { + val i = 1 + if (i.getter != 1) return "getter failed" + + i.setter = 1 + if (i.setter != 1) return "setter failed" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/labels/propertyAccessorObject.kt b/backend.native/tests/external/codegen/blackbox/labels/propertyAccessorObject.kt new file mode 100644 index 00000000000..1fc9f25aa82 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/labels/propertyAccessorObject.kt @@ -0,0 +1,19 @@ +interface Base { + fun foo(): Int +} + +val Int.getter: Int + get() { + return object : Base { + override fun foo(): Int { + return this@getter + } + }.foo() + } + +fun box(): String { + val i = 1 + if (i.getter != 1) return "getter failed" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/labels/propertyInClassAccessor.kt b/backend.native/tests/external/codegen/blackbox/labels/propertyInClassAccessor.kt new file mode 100644 index 00000000000..21cfd6428d9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/labels/propertyInClassAccessor.kt @@ -0,0 +1,17 @@ +class Test { + val Int.innerGetter: Int + get() { + return this@innerGetter + } + + fun test(): Int { + val i = 1 + if (i.innerGetter != 1) return 0 + return 1 + } +} + +fun box(): String { + if (Test().test() != 1) return "inner getter or setter failed" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/exceptionInFieldInitializer.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/exceptionInFieldInitializer.kt new file mode 100644 index 00000000000..f086e0ca2ff --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/exceptionInFieldInitializer.kt @@ -0,0 +1,32 @@ +class A(val p: String) { + val prop: String = throw RuntimeException() +} + +class B(val p: String) { + val prop: String = if (p == "test") "OK" else throw RuntimeException() +} + +fun box(): String { + var result = "fail" + try { + if (A("test").prop != "OK") return "fail 1" + } + catch (e: RuntimeException) { + result = "OK" + } + if (result != "OK") return "fail 1: $result" + + + if (B("test").prop != "OK") return "fail 2" + + + result = "fail" + try { + if (B("fail").prop != "OK") return "fail 3" + } + catch (e: RuntimeException) { + return "OK" + } + + return "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/ifElse.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/ifElse.kt new file mode 100644 index 00000000000..0f683860b24 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/ifElse.kt @@ -0,0 +1,34 @@ +class A (val p: String, p1: String, p2: String) { + + var cond1 :String = "" + + var cond2 :String = "" + + val prop: String = if (p == "test") p1 else p2 + + val prop1 = if (cond1(p)) p1 else false + + val prop2 = if (cond2(p)) true else false + + fun cond1(p: String): Boolean { + cond1 = "cond1" + return p == "test" + } + + fun cond2(p: String): Boolean { + cond2 = "cond2" + return p == "test" + } +} + +fun box(): String { + val a = A("test", "OK", "fail") + + if (a.prop != "OK") return "fail 1" + + if (a.cond1 != "cond1") return "fail 2" + + if (a.cond2 != "cond2") return "fail 3" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/increment.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/increment.kt new file mode 100644 index 00000000000..40369fff4af --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/increment.kt @@ -0,0 +1,31 @@ +var holder = "" +var globalA: A = A(-1) + get(): A { + holder += "getA" + return field + } + + +class A(val p: Int) { + + var prop = this + + operator fun inc(): A { + return A(p+1) + } + + +} + +fun box(): String { + var a = A(1) + ++a + if (a.p != 2) return "fail 1: ${a.p} $holder" + + globalA = A(1) + ++(globalA.prop) + val holderValue = holder; + if (globalA.p != 1 || globalA.prop.p != 2 || holderValue != "getA") return "fail 2: ${a.p} ${a.prop.p} ${holderValue}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateConstantCompare.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateConstantCompare.kt new file mode 100644 index 00000000000..f68757d7588 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateConstantCompare.kt @@ -0,0 +1,7 @@ +fun box(): String { + if (!(1 < 2)) { + return "fail" + } + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateFalse.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateFalse.kt new file mode 100644 index 00000000000..fd5ef04626e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateFalse.kt @@ -0,0 +1,7 @@ +fun box(): String { + if (!false) { + return "OK" + } else { + return "fail" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateFalseVar.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateFalseVar.kt new file mode 100644 index 00000000000..c4ad074824a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateFalseVar.kt @@ -0,0 +1,8 @@ +fun box(): String { + var p = 2 < 1; + if (!p) { + return "OK" + } else { + return "fail" + } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateFalseVarChain.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateFalseVarChain.kt new file mode 100644 index 00000000000..8f89b14fe90 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateFalseVarChain.kt @@ -0,0 +1,8 @@ +fun box(): String { + val p = 2 < 1; + if (!!!!!p) { + return "OK" + } else { + return "fail" + } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateObjectComp.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateObjectComp.kt new file mode 100644 index 00000000000..58e15f4de93 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateObjectComp.kt @@ -0,0 +1,9 @@ +val p: Int? = 1; +val z: Int? = 2; + +fun box(): String { + if (!(p!! == z!!)) { + return "OK" + } + return "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateObjectComp2.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateObjectComp2.kt new file mode 100644 index 00000000000..e1a13f17cc9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateObjectComp2.kt @@ -0,0 +1,9 @@ +val p: Int? = 1; +val z: Int? = 2; + +fun box(): String { + if (!(p!! < z!!)) { + return "fail" + } + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateTrue.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateTrue.kt new file mode 100644 index 00000000000..487ec8c27a8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateTrue.kt @@ -0,0 +1,7 @@ +fun box(): String { + if (!true) { + return "fail" + } else { + return "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateTrueVar.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateTrueVar.kt new file mode 100644 index 00000000000..2c651614453 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/negateTrueVar.kt @@ -0,0 +1,8 @@ +fun box(): String { + var p = 1 < 2; + if (!p) { + return "fail" + } else { + return "OK" + } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/noOptimization.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/noOptimization.kt new file mode 100644 index 00000000000..1437d56484b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/optimizations/noOptimization.kt @@ -0,0 +1,28 @@ +class A +class B + +var holder = 0 + +operator fun A.not(): A { + holder++ + return this; +} + +operator fun B.not(): Boolean { + holder++ + return false; +} + +fun box(): String { + !!!!!A() + if (holder != 5) return "fail 1" + + holder = 0; + if (!!!B() || holder != 1) return "fail 2" + + if (!B() != false) return "fail 3" + + if (!!B() != true) return "fail 4" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/safeAssign.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/safeAssign.kt new file mode 100644 index 00000000000..8019455b3da --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/safeAssign.kt @@ -0,0 +1,10 @@ +class Shape(var result: String) { + +} + +fun box(): String { + var a : Shape? = Shape("fail"); + a?.result = "OK"; + + return a!!.result +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/safeAssignComplex.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/safeAssignComplex.kt new file mode 100644 index 00000000000..6dd9cac91de --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/safeAssignComplex.kt @@ -0,0 +1,34 @@ +var holder = "" + +var mainShape: Shape? = null + +fun getShape(): Shape? { + holder += "getShape1()" + mainShape = Shape("fail") + return mainShape +} + +fun getOK(): String { + holder += "->OK" + return "OK" +} + + +class Shape(var result: String) { + + var innerShape: Shape? = null + + fun getShape2(): Shape? { + holder += "->getShape2()" + innerShape = Shape(result) + return innerShape + } +} + +fun box(): String { + getShape()?.getShape2()?.result = getOK(); + + if (holder != "getShape1()->getShape2()->OK") return "fail $holder" + + return mainShape!!.innerShape!!.result +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/safeCallAndArray.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/safeCallAndArray.kt new file mode 100644 index 00000000000..90b61d66b5f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/safeCallAndArray.kt @@ -0,0 +1,11 @@ +class C { + fun calc() : String { + return "OK" + } +} + +fun box(): String? { + val c: C? = C() + val arrayList = arrayOf(c?.calc(), "") + return arrayList[0] +} diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/toString.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/toString.kt new file mode 100644 index 00000000000..a71276879e8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/toString.kt @@ -0,0 +1,12 @@ +class A (val p: String) { + + val _kind: String = "$p" + +} + +fun box(): String { + + if (A("OK")._kind != "OK") return "fail" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/tryCatchExpression.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/tryCatchExpression.kt new file mode 100644 index 00000000000..8617a79e1cf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/tryCatchExpression.kt @@ -0,0 +1,13 @@ +class A { + val p : Int = try{ + 1 + } catch(e: Exception) { + throw RuntimeException() + } +} + +fun box() : String { + if (A().p != 1) return "fail 1" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/lazyCodegen/when.kt b/backend.native/tests/external/codegen/blackbox/lazyCodegen/when.kt new file mode 100644 index 00000000000..3953b4f0b2c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/lazyCodegen/when.kt @@ -0,0 +1,15 @@ +class A (val p: String) { + + val _kind: String = when { + p == "test" -> "OK" + else -> "fail" + } + +} + +fun box(): String { + + if (A("test")._kind != "OK") return "fail" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/anonymousObjectInInitializer.kt b/backend.native/tests/external/codegen/blackbox/localClasses/anonymousObjectInInitializer.kt new file mode 100644 index 00000000000..ef9b826ff07 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/anonymousObjectInInitializer.kt @@ -0,0 +1,13 @@ +class A { + var a: String = "Fail" + + init { + a = object { + override fun toString(): String = "OK" + }.toString() + } +} + +fun box() : String { + return A().a +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/anonymousObjectInParameterInitializer.kt b/backend.native/tests/external/codegen/blackbox/localClasses/anonymousObjectInParameterInitializer.kt new file mode 100644 index 00000000000..e5a27ccdbc4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/anonymousObjectInParameterInitializer.kt @@ -0,0 +1,9 @@ +class A( + val a: String = object { + override fun toString(): String = "OK" + }.toString() +) + +fun box() : String { + return A().a +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/closureOfInnerLocalClass.kt b/backend.native/tests/external/codegen/blackbox/localClasses/closureOfInnerLocalClass.kt new file mode 100644 index 00000000000..c01ad313420 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/closureOfInnerLocalClass.kt @@ -0,0 +1,28 @@ +// Enable for JVM backend when KT-8120 gets fixed +// TARGET_BACKEND: JS + +fun box(): String { + var log = "" + + var s: Any? = null + for (t in arrayOf("1", "2", "3")) { + class C() { + val y = t + + inner class D() { + fun copyOuter() = C() + } + } + + if (s == null) { + s = C() + } + + val c = (s as C).D().copyOuter() + log += c.y + } + + if (log != "111") return "fail: ${log}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/closureOfLambdaInLocalClass.kt b/backend.native/tests/external/codegen/blackbox/localClasses/closureOfLambdaInLocalClass.kt new file mode 100644 index 00000000000..3cae7289280 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/closureOfLambdaInLocalClass.kt @@ -0,0 +1,38 @@ +fun box(): String { + var log = "" + + var s: Any? = null + for (t in arrayOf("1", "2", "3")) { + class A() { + fun foo() = { t } + } + + if (s == null) { + s = A() + } + + log += (s as A).foo()() + } + + if (log != "111") return "fail1: ${log}" + + s = null + log = "" + for (t in arrayOf("1", "2", "3")) { + class B() { + val y = t + + fun foo() = { y } + } + + if (s == null) { + s = B() + } + + log += (s as B).foo()() + } + + if (log != "111") return "fail2: ${log}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/closureWithSelfInstantiation.kt b/backend.native/tests/external/codegen/blackbox/localClasses/closureWithSelfInstantiation.kt new file mode 100644 index 00000000000..206ccc3d5f7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/closureWithSelfInstantiation.kt @@ -0,0 +1,78 @@ +// Enable for JVM backend when KT-8120 gets fixed +// TARGET_BACKEND: JS + +fun box(): String { + val capturedInConstructor = 1 + val capturedInBody = 10 + var log = "" + + class A(var x: Int) { + var y = 0 + + fun copy(): A { + log += "A.copy;" + val result = A(x) + result.y += capturedInBody + return result + } + + init { + log += "A.;" + y += x + capturedInConstructor + } + } + + val a = A(100).copy() + if (a.y != 111) return "fail1a: ${a.y}" + if (a.x != 100) return "fail1b: ${a.x}" + + + class B(var x: Int) { + var y = 0 + + fun copier(): () -> B { + log += "B.copier;" + return { + log += "B.copy;" + val result = B(x) + result.y += capturedInBody + result + } + } + + init { + y += x + capturedInConstructor + log += "B.;" + } + } + + val b = B(100).copier()() + if (b.y != 111) return "fail2a: ${b.y}" + if (b.x != 100) return "fail2b: ${b.x}" + + class C(var x: Int) { + var y = 0 + + inner class D() { + fun copyOuter(): C { + log += "D.copyOuter;" + val result = C(x) + result.y += capturedInBody + return result + } + } + + init { + log += "C.;" + y += x + capturedInConstructor + } + } + + val c = C(100).D().copyOuter() + if (c.y != 111) return "fail3a: ${c.y}" + if (c.x != 100) return "fail3b: ${c.x}" + + if (log != "A.;A.copy;A.;B.;B.copier;B.copy;B.;C.;D.copyOuter;C.;") return "fail_log: $log" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/inExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/localClasses/inExtensionFunction.kt new file mode 100644 index 00000000000..0a4fbfbbbf0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/inExtensionFunction.kt @@ -0,0 +1,17 @@ +package test + +fun A.a(): String { + class B { + val b : String + get() = this@a.s + } + return B().b +} + +class A { + val s : String = "OK" +} + +fun box() : String { + return A().a() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/inExtensionProperty.kt b/backend.native/tests/external/codegen/blackbox/localClasses/inExtensionProperty.kt new file mode 100644 index 00000000000..6b0ed7cb97d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/inExtensionProperty.kt @@ -0,0 +1,18 @@ +package test + +val A.a: String + get() { + class B { + val b : String + get() = this@a.s + } + return B().b + } + +class A { + val s : String = "OK" +} + +fun box() : String { + return A().a +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/inLocalExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/localClasses/inLocalExtensionFunction.kt new file mode 100644 index 00000000000..d7231d40d3d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/inLocalExtensionFunction.kt @@ -0,0 +1,24 @@ +package test + +class C(val s : String) { + fun A.a(): String { + class B { + val b : String + get() = this@a.s + this@C.s + } + return B().b + } + + fun test(a : A) : String { + return a.a() + } +} + +class A(val s: String) { + + +} + +fun box() : String { + return C("K").test(A("O")) +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/inLocalExtensionProperty.kt b/backend.native/tests/external/codegen/blackbox/localClasses/inLocalExtensionProperty.kt new file mode 100644 index 00000000000..6a628f41320 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/inLocalExtensionProperty.kt @@ -0,0 +1,23 @@ +package test + +class C(val s : String) { + val A.a: String + get() { + class B { + val b : String + get() = this@a.s + this@C.s + } + return B().b + } + + fun test(a : A) : String { + return a.a + } +} + +class A(val s: String) { +} + +fun box() : String { + return C("K").test(A("O")) +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/innerClassInLocalClass.kt b/backend.native/tests/external/codegen/blackbox/localClasses/innerClassInLocalClass.kt new file mode 100644 index 00000000000..72d84e5ddac --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/innerClassInLocalClass.kt @@ -0,0 +1,17 @@ +class A { + val a = 1 + fun calc () : Int { + class B() { + val b = 2 + inner class C { + val c = 3 + fun calc() = this@A.a + this@B.b + this.c + } + } + return B().C().calc() + } +} + +fun box() : String { + return if (A().calc() == 6) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/innerOfLocalCaptureExtensionReceiver.kt b/backend.native/tests/external/codegen/blackbox/localClasses/innerOfLocalCaptureExtensionReceiver.kt new file mode 100644 index 00000000000..ba3a0df632a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/innerOfLocalCaptureExtensionReceiver.kt @@ -0,0 +1,15 @@ +fun String.bar(): String { + open class Local { + fun result() = this@bar + } + + class Outer { + inner class Inner : Local() { + fun outer() = this@Outer + } + } + + return Outer().Inner().result() +} + +fun box() = "OK".bar() diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/kt2700.kt b/backend.native/tests/external/codegen/blackbox/localClasses/kt2700.kt new file mode 100644 index 00000000000..3baacf0b21f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/kt2700.kt @@ -0,0 +1,17 @@ +package a.b + +interface Test { + fun invoke(): String { + return "OK" + } +} + +private val a : Test = { + object : Test { + + } +}() + +fun box(): String { + return a.invoke(); +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/kt2873.kt b/backend.native/tests/external/codegen/blackbox/localClasses/kt2873.kt new file mode 100644 index 00000000000..6bb8dafadfd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/kt2873.kt @@ -0,0 +1,15 @@ +fun foo() : String { + val u = { + class B(val data : String) + B("OK").data + } + return u() +} + +fun main(args: Array) { + foo() +} + +fun box(): String { + return foo() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/kt3210.kt b/backend.native/tests/external/codegen/blackbox/localClasses/kt3210.kt new file mode 100644 index 00000000000..12c9b1cba6e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/kt3210.kt @@ -0,0 +1,32 @@ +package org.example + +interface SomeTrait {} + +interface KotlinProcessor { + fun execute(callback: KotlinCallback?); +} + +interface KotlinCallback { + fun on(t : T); +} + +public class Test(name : String) : KotlinProcessor { + public override fun execute(callback: KotlinCallback?) { + if(callback != null) { + class InlineTrait : SomeTrait {} + + var inlineTrait = InlineTrait() + callback.on(inlineTrait) + } + } +} + +fun box() : String { + var f = "fail" + Test("OK").execute(object : KotlinCallback { + override fun on(t: SomeTrait) { + f = "OK" + } + }) + return f +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/kt3389.kt b/backend.native/tests/external/codegen/blackbox/localClasses/kt3389.kt new file mode 100644 index 00000000000..abb515b1688 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/kt3389.kt @@ -0,0 +1,14 @@ +package t + +class Reproduce { + + fun test(): String { + data class Foo(val bar: String, val baz: Int) + val foo = Foo("OK", 5) + return foo.bar + } +} + +fun box() : String { + return Reproduce().test() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/kt3584.kt b/backend.native/tests/external/codegen/blackbox/localClasses/kt3584.kt new file mode 100644 index 00000000000..21cdb764faa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/kt3584.kt @@ -0,0 +1,13 @@ +fun box(): String { + val s = "captured"; + + class A(val param: String = "OK") { + val s2 = s + param + } + + if (A().s2 != "capturedOK") return "fail 1: ${A().s2}" + + if (A("Test").s2 != "capturedTest") return "fail 2: ${A("Test").s2}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/kt4174.kt b/backend.native/tests/external/codegen/blackbox/localClasses/kt4174.kt new file mode 100644 index 00000000000..56a73053979 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/kt4174.kt @@ -0,0 +1,25 @@ +open class C(val s: String) { + fun test(): String { + return s + } +} + +class B(var x: String) { + fun foo(): String { + var s = "OK" + class Z : C(s) {} + return Z().test() + } + + fun foo2(): String { + class Y : C(x) {} + return Y().test() + } +} + + +fun box(): String { + val b = B("OK") + if (b.foo() != "OK") return "fail: ${b.foo()}" + return b.foo2() +} diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/localClass.kt b/backend.native/tests/external/codegen/blackbox/localClasses/localClass.kt new file mode 100644 index 00000000000..d8cdb7552fd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/localClass.kt @@ -0,0 +1,12 @@ +class A { + fun a () : String { + class B() { + fun s() : String = "OK" + } + return B().s() + } +} + +fun box() : String { + return A().a() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/localClassCaptureExtensionReceiver.kt b/backend.native/tests/external/codegen/blackbox/localClasses/localClassCaptureExtensionReceiver.kt new file mode 100644 index 00000000000..89ee7e3754f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/localClassCaptureExtensionReceiver.kt @@ -0,0 +1,14 @@ +class Outer { + fun String.id(): String { + class Local(unused: Long) { + fun result() = this@id + fun outer() = this@Outer + } + + return Local(42L).result() + } + + fun result(): String = "OK".id() +} + +fun box() = Outer().result() diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/localClassInInitializer.kt b/backend.native/tests/external/codegen/blackbox/localClasses/localClassInInitializer.kt new file mode 100644 index 00000000000..0dafae38048 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/localClassInInitializer.kt @@ -0,0 +1,19 @@ +class A { + var a: String = "Fail" + + init { + open class B() { + open fun s() : String = "O" + } + + val o = object : B() { + override fun s(): String = "K" + } + + a = B().s() + o.s() + } +} + +fun box() : String { + return A().a +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/localClassInParameterInitializer.kt b/backend.native/tests/external/codegen/blackbox/localClasses/localClassInParameterInitializer.kt new file mode 100644 index 00000000000..2b5c62666e6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/localClassInParameterInitializer.kt @@ -0,0 +1,17 @@ +class A( + val a: String = { + open class B() { + open fun s() : String = "O" + } + + val o = object : B() { + override fun s(): String = "K" + } + + B().s() + o.s() + }() +) + +fun box() : String { + return A().a +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/localDataClass.kt b/backend.native/tests/external/codegen/blackbox/localClasses/localDataClass.kt new file mode 100644 index 00000000000..33cf16258d2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/localDataClass.kt @@ -0,0 +1,17 @@ +fun box(): String { + val capturedInConstructor = 1 + + data class A(var x: Int) { + var y = 0 + + init { + y += x + capturedInConstructor + } + } + + val a = A(100).copy() + if (a.y != 101) return "fail1a: ${a.y}" + if (a.x != 100) return "fail1b: ${a.x}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/localExtendsInnerAndReferencesOuterMember.kt b/backend.native/tests/external/codegen/blackbox/localClasses/localExtendsInnerAndReferencesOuterMember.kt new file mode 100644 index 00000000000..f5520406363 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/localExtendsInnerAndReferencesOuterMember.kt @@ -0,0 +1,14 @@ +class A { + fun box(): String { + class Local : Inner() { + val u = foo() + } + val u = Local().u + return if (u == 42) "OK" else "Fail $u" + } + + open inner class Inner + fun foo() = 42 +} + +fun box() = A().box() diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/noclosure.kt b/backend.native/tests/external/codegen/blackbox/localClasses/noclosure.kt new file mode 100644 index 00000000000..8f9417505e7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/noclosure.kt @@ -0,0 +1,11 @@ +fun box(): String { + open class K { + val o = "O" + } + + class Bar : K() { + val k = "K" + } + + return K().o + Bar().k +} diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/object.kt b/backend.native/tests/external/codegen/blackbox/localClasses/object.kt new file mode 100644 index 00000000000..a96a9237f68 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/object.kt @@ -0,0 +1,7 @@ +fun box(): String { + val k = object { + val ok = "OK" + } + + return k.ok +} diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/ownClosureOfInnerLocalClass.kt b/backend.native/tests/external/codegen/blackbox/localClasses/ownClosureOfInnerLocalClass.kt new file mode 100644 index 00000000000..c978f8b9c62 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/ownClosureOfInnerLocalClass.kt @@ -0,0 +1,24 @@ +fun box(): String { + var log = "" + + var s: Any? = null + for (t in arrayOf("1", "2", "3")) { + class C() { + val y = t + + inner class D() { + fun foo() = "($y;$t)" + } + } + + if (s == null) { + s = C() + } + + log += (s as C).D().foo() + } + + if (log != "(1;1)(1;1)(1;1)") return "fail: ${log}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/localClasses/withclosure.kt b/backend.native/tests/external/codegen/blackbox/localClasses/withclosure.kt new file mode 100644 index 00000000000..b9dc2f5bee3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/localClasses/withclosure.kt @@ -0,0 +1,8 @@ +fun box(): String { + val x = "OK" + class Aaa { + val y = x + } + + return Aaa().y +} diff --git a/backend.native/tests/external/codegen/blackbox/mangling/field.kt b/backend.native/tests/external/codegen/blackbox/mangling/field.kt new file mode 100644 index 00000000000..d4805116073 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/mangling/field.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +package test + +internal val noMangling = 1; + +class Z { + internal var noMangling = 1; +} + +fun box(): String { + val clazz = Z::class.java + val classField = clazz.getDeclaredField("noMangling") + if (classField == null) return "Class internal backing field should exist" + + val topLevel = Class.forName("test.FieldKt").getDeclaredField("noMangling") + if (topLevel == null) return "Top level internal backing field should exist" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/mangling/fun.kt b/backend.native/tests/external/codegen/blackbox/mangling/fun.kt new file mode 100644 index 00000000000..648f8620f80 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/mangling/fun.kt @@ -0,0 +1,27 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +package test + +internal fun noMangling() = 1; + +class Z { + internal fun mangled() = 1; +} + +fun box(): String { + val clazz = Z::class.java + val declaredMethods = clazz.declaredMethods + + val mangled = declaredMethods.firstOrNull { + it.name.startsWith("mangled$") + } + if (mangled == null) return "Class internal function should exist" + + val topLevel = Class.forName("test.FunKt").getMethod("noMangling") + if (topLevel == null) return "Top level internal function should exist" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/mangling/internalOverride.kt b/backend.native/tests/external/codegen/blackbox/mangling/internalOverride.kt new file mode 100644 index 00000000000..b8ac1e207a1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/mangling/internalOverride.kt @@ -0,0 +1,29 @@ +open class A { + internal open val field = "AF" + + internal open fun test(): String = "AM" +} + +fun invokeOnA(a: A) = a.test() + a.field + +class Z : A() { + override val field: String = "ZF" + + override fun test(): String = "ZM" +} + +fun box() : String { + var invokeOnA = invokeOnA(A()) + if (invokeOnA != "AMAF") return "fail 1: $invokeOnA" + + invokeOnA = invokeOnA(Z()) + if (invokeOnA != "ZMZF") return "fail 2: $invokeOnA" + + val z = Z().test() + if (z != "ZM") return "fail 3: $z" + + val f = Z().field + if (f != "ZF") return "fail 4: $f" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/mangling/internalOverrideSuperCall.kt b/backend.native/tests/external/codegen/blackbox/mangling/internalOverrideSuperCall.kt new file mode 100644 index 00000000000..64424c1dd80 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/mangling/internalOverrideSuperCall.kt @@ -0,0 +1,21 @@ +open class A { + internal open val field = "F" + + internal open fun test(): String = "A" +} + +class Z : A() { + override fun test(): String = super.test() + + override val field = super.field +} + +fun box() : String { + val z = Z().test() + if (z != "A") return "fail 1: $z" + + val f = Z().field + if (f != "F") return "fail 2: $f" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/mangling/noOverrideWithJava.kt b/backend.native/tests/external/codegen/blackbox/mangling/noOverrideWithJava.kt new file mode 100644 index 00000000000..0e5a23013c9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/mangling/noOverrideWithJava.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: JavaClass.java + +public class JavaClass extends A { + public String test() { + return "Java"; + } +} + +// FILE: test.kt + +open class A { + internal open fun test(): String = "Kotlin" +} + +fun box(): String { + if (A().test() != "Kotlin") return "fail 1: ${A().test()}" + + if (JavaClass().test() != "Java") return "fail 2: ${JavaClass().test()}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/mangling/publicOverride.kt b/backend.native/tests/external/codegen/blackbox/mangling/publicOverride.kt new file mode 100644 index 00000000000..0087a1fbc66 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/mangling/publicOverride.kt @@ -0,0 +1,29 @@ +open class A { + internal open val field = "AF" + + internal open fun test(): String = "AM" +} + +fun invokeOnA(a: A) = a.test() + a.field + +class Z : A() { + public override val field: String = "ZF" + + public override fun test(): String = "ZM" +} + +fun box() : String { + var invokeOnA = invokeOnA(A()) + if (invokeOnA != "AMAF") return "fail 1: $invokeOnA" + + invokeOnA = invokeOnA(Z()) + if (invokeOnA != "ZMZF") return "fail 2: $invokeOnA" + + val z = Z().test() + if (z != "ZM") return "fail 3: $z" + + val f = Z().field + if (f != "ZF") return "fail 4: $f" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/mangling/publicOverrideSuperCall.kt b/backend.native/tests/external/codegen/blackbox/mangling/publicOverrideSuperCall.kt new file mode 100644 index 00000000000..422f510101e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/mangling/publicOverrideSuperCall.kt @@ -0,0 +1,21 @@ +open class A { + internal open val field = "F" + + internal open fun test(): String = "A" +} + +class Z : A() { + public override fun test(): String = super.test() + + public override val field = super.field +} + +fun box() : String { + val z = Z().test() + if (z != "A") return "fail 1: $z" + + val f = Z().field + if (f != "F") return "fail 2: $f" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/ComplexInitializer.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/ComplexInitializer.kt new file mode 100644 index 00000000000..14e38239d17 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/ComplexInitializer.kt @@ -0,0 +1,12 @@ +class A { + operator fun component1() = 1 + operator fun component2() = 2 +} + +fun A.getA() = this + +fun box() : String { + val (a, b) = A().getA().getA() + + return if (a == 1 && b == 2) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/SimpleVals.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/SimpleVals.kt new file mode 100644 index 00000000000..9f438f3fe71 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/SimpleVals.kt @@ -0,0 +1,9 @@ +class A { + operator fun component1() = 1 + operator fun component2() = 2 +} + +fun box() : String { + val (a, b) = A() + return if (a == 1 && b == 2) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/SimpleValsExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/SimpleValsExtensions.kt new file mode 100644 index 00000000000..cab08120cb0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/SimpleValsExtensions.kt @@ -0,0 +1,10 @@ +class A { +} + +operator fun A.component1() = 1 +operator fun A.component2() = 2 + +fun box() : String { + val (a, b) = A() + return if (a == 1 && b == 2) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/SimpleVarsExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/SimpleVarsExtensions.kt new file mode 100644 index 00000000000..525d1234901 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/SimpleVarsExtensions.kt @@ -0,0 +1,10 @@ +class A { + operator fun component1() = 1 + operator fun component2() = 2 +} + +fun box() : String { + var (a, b) = A() + a = b + return if (a == 2 && b == 2) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/UnderscoreNames.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/UnderscoreNames.kt new file mode 100644 index 00000000000..12dfc941fb6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/UnderscoreNames.kt @@ -0,0 +1,14 @@ +class A { + operator fun component1() = 1 + operator fun component2() = 2 +} + +fun box() : String { + val (_, b) = A() + + val (a, _) = A() + + val (`_`, c) = A() + + return if (a == 1 && b == 2 && _ == 1 && c == 2) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/ValCapturedInFunctionLiteral.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/ValCapturedInFunctionLiteral.kt new file mode 100644 index 00000000000..4bf9bdcd08c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/ValCapturedInFunctionLiteral.kt @@ -0,0 +1,13 @@ +class A { + operator fun component1() = 1 + operator fun component2() = 2 +} + +fun box() : String { + val (a, b) = A() + + val run = { + a + } + return if (run() == 1 && b == 2) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/ValCapturedInLocalFunction.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/ValCapturedInLocalFunction.kt new file mode 100644 index 00000000000..91dfb1d7eb5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/ValCapturedInLocalFunction.kt @@ -0,0 +1,13 @@ +class A { + operator fun component1() = 1 + operator fun component2() = 2 +} + +fun box() : String { + val (a, b) = A() + + fun run(): Int { + return a + } + return if (run() == 1 && b == 2) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/ValCapturedInObjectLiteral.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/ValCapturedInObjectLiteral.kt new file mode 100644 index 00000000000..9e194386e6a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/ValCapturedInObjectLiteral.kt @@ -0,0 +1,16 @@ +class A { + operator fun component1() = 1 + operator fun component2() = 2 +} + + +fun box() : String { + val (a, b) = A() + + val local = object { + public fun run() : Int { + return a + } + } + return if (local.run() == 1 && b == 2) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/VarCapturedInFunctionLiteral.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/VarCapturedInFunctionLiteral.kt new file mode 100644 index 00000000000..e0eb2cb5edd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/VarCapturedInFunctionLiteral.kt @@ -0,0 +1,15 @@ +class A { + operator fun component1() = 1 + operator fun component2() = 2 +} + + +fun box() : String { + var (a, b) = A() + + val local = { + a = 3 + } + local() + return if (a == 3 && b == 2) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/VarCapturedInLocalFunction.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/VarCapturedInLocalFunction.kt new file mode 100644 index 00000000000..5c2a87c9d65 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/VarCapturedInLocalFunction.kt @@ -0,0 +1,15 @@ +class A { +} + +operator fun A.component1() = 1 +operator fun A.component2() = 2 + +fun box() : String { + var (a, b) = A() + + fun local() { + a = 3 + } + local() + return if (a == 3 && b == 2) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/VarCapturedInObjectLiteral.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/VarCapturedInObjectLiteral.kt new file mode 100644 index 00000000000..48534b362c6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/VarCapturedInObjectLiteral.kt @@ -0,0 +1,17 @@ +class A { + operator fun component1() = 1 + operator fun component2() = 2 +} + + +fun box() : String { + var (a, b) = A() + + val local = object { + public fun run() { + a = 3 + } + } + local.run() + return if (a == 3 && b == 2) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/component.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/component.kt new file mode 100644 index 00000000000..efd446f8df6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/component.kt @@ -0,0 +1,19 @@ +// WITH_RUNTIME + +class S(val a: String, val b: String) { + operator fun component1() : String = a + operator fun component2() : String = b +} + +operator fun S.component3() = ((a + b) as String).substring(2) + +class Tester() { + fun box() : String { + val (o,k,ok,ok2) = S("O","K") + return o + k + ok + ok2 + } + + operator fun S.component4() = ((a + b) as String).substring(2) +} + +fun box() = Tester().box() diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/MultiDeclFor.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/MultiDeclFor.kt new file mode 100644 index 00000000000..d3fce253d5a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/MultiDeclFor.kt @@ -0,0 +1,21 @@ +class C(val i: Int) { + operator fun component1() = i + 1 + operator fun component2() = i + 2 +} + +fun doTest(l : ArrayList): String { + var s = "" + for ((a, b) in l) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val l = ArrayList() + l.add(C(0)) + l.add(C(1)) + l.add(C(2)) + val s = doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/MultiDeclForComponentExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/MultiDeclForComponentExtensions.kt new file mode 100644 index 00000000000..fb470307de3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/MultiDeclForComponentExtensions.kt @@ -0,0 +1,22 @@ +class C(val i: Int) { +} + +operator fun C.component1() = i + 1 +operator fun C.component2() = i + 2 + +fun doTest(l : ArrayList): String { + var s = "" + for ((a, b) in l) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val l = ArrayList() + l.add(C(0)) + l.add(C(1)) + l.add(C(2)) + val s = doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/MultiDeclForComponentMemberExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/MultiDeclForComponentMemberExtensions.kt new file mode 100644 index 00000000000..344e2051fc9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/MultiDeclForComponentMemberExtensions.kt @@ -0,0 +1,24 @@ +class C(val i: Int) { +} + +class M { + operator fun C.component1() = i + 1 + operator fun C.component2() = i + 2 + + fun doTest(l : ArrayList): String { + var s = "" + for ((a, b) in l) { + s += "$a:$b;" + } + return s + } +} + +fun box(): String { + val l = ArrayList() + l.add(C(0)) + l.add(C(1)) + l.add(C(2)) + val s = M().doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt new file mode 100644 index 00000000000..2b223cd505e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt @@ -0,0 +1,24 @@ +class C(val i: Int) { +} + +class M { + operator fun C.component1() = i + 1 + operator fun C.component2() = i + 2 +} + +fun M.doTest(l : ArrayList): String { + var s = "" + for ((a, b) in l) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val l = ArrayList() + l.add(C(0)) + l.add(C(1)) + l.add(C(2)) + val s = M().doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/MultiDeclForValCaptured.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/MultiDeclForValCaptured.kt new file mode 100644 index 00000000000..a744e0370ee --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/MultiDeclForValCaptured.kt @@ -0,0 +1,21 @@ +class C(val i: Int) { + operator fun component1() = i + 1 + operator fun component2() = i + 2 +} + +fun doTest(l : ArrayList): String { + var s = "" + for ((a, b) in l) { + s += {"$a:$b;"}() + } + return s +} + +fun box(): String { + val l = ArrayList() + l.add(C(0)) + l.add(C(1)) + l.add(C(2)) + val s = doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/longIterator/MultiDeclForComponentExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/longIterator/MultiDeclForComponentExtensions.kt new file mode 100644 index 00000000000..e9facb62192 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/longIterator/MultiDeclForComponentExtensions.kt @@ -0,0 +1,19 @@ +operator fun Long.component1() = this + 1 +operator fun Long.component2() = this + 2 + +fun doTest(l : ArrayList): String { + var s = "" + for ((a, b) in l) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val l = ArrayList() + l.add(0) + l.add(1) + l.add(2) + val s = doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/longIterator/MultiDeclForComponentExtensionsValCaptured.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/longIterator/MultiDeclForComponentExtensionsValCaptured.kt new file mode 100644 index 00000000000..7afc1023d61 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/longIterator/MultiDeclForComponentExtensionsValCaptured.kt @@ -0,0 +1,19 @@ +operator fun Long.component1() = this + 1 +operator fun Long.component2() = this + 2 + +fun doTest(l : ArrayList): String { + var s = "" + for ((a, b) in l) { + s += {"$a:$b;"}() + } + return s +} + +fun box(): String { + val l = ArrayList() + l.add(0) + l.add(1) + l.add(2) + val s = doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/longIterator/MultiDeclForComponentMemberExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/longIterator/MultiDeclForComponentMemberExtensions.kt new file mode 100644 index 00000000000..499b2e18356 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/longIterator/MultiDeclForComponentMemberExtensions.kt @@ -0,0 +1,21 @@ +class M { + operator fun Long.component1() = this + 1 + operator fun Long.component2() = this + 2 + + fun doTest(l : ArrayList): String { + var s = "" + for ((a, b) in l) { + s += "$a:$b;" + } + return s + } +} + +fun box(): String { + val l = ArrayList() + l.add(0) + l.add(1) + l.add(2) + val s = M().doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/longIterator/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/longIterator/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt new file mode 100644 index 00000000000..b20eb9d7453 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forIterator/longIterator/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt @@ -0,0 +1,21 @@ +class M { + operator fun Long.component1() = this + 1 + operator fun Long.component2() = this + 2 +} + +fun M.doTest(l : ArrayList): String { + var s = "" + for ((a, b) in l) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val l = ArrayList() + l.add(0) + l.add(1) + l.add(2) + val s = M().doTest(l) + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/MultiDeclFor.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/MultiDeclFor.kt new file mode 100644 index 00000000000..ceabb3396b0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/MultiDeclFor.kt @@ -0,0 +1,34 @@ +class Range(val from : C, val to: C) { + operator fun iterator() = It(from, to) +} + +class It(val from: C, val to: C) { + var c = from.i + + operator fun next(): C { + val next = C(c) + c++ + return next + } + + operator fun hasNext(): Boolean = c <= to.i +} + +class C(val i : Int) { + operator fun component1() = i + 1 + operator fun component2() = i + 2 + operator fun rangeTo(c: C) = Range(this, c) +} + +fun doTest(): String { + var s = "" + for ((a, b) in C(0)..C(2)) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/MultiDeclForComponentExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/MultiDeclForComponentExtensions.kt new file mode 100644 index 00000000000..edcd9c1188e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/MultiDeclForComponentExtensions.kt @@ -0,0 +1,34 @@ +class Range(val from : C, val to: C) { + operator fun iterator() = It(from, to) +} + +class It(val from: C, val to: C) { + var c = from.i + + operator fun next(): C { + val next = C(c) + c++ + return next + } + + operator fun hasNext(): Boolean = c <= to.i +} + +class C(val i : Int) { + operator fun rangeTo(c: C) = Range(this, c) +} +operator fun C.component1() = i + 1 +operator fun C.component2() = i + 2 + +fun doTest(): String { + var s = "" + for ((a, b) in C(0)..C(2)) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/MultiDeclForComponentMemberExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/MultiDeclForComponentMemberExtensions.kt new file mode 100644 index 00000000000..3692148f5b5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/MultiDeclForComponentMemberExtensions.kt @@ -0,0 +1,38 @@ +class Range(val from : C, val to: C) { + operator fun iterator() = It(from, to) +} + +class It(val from: C, val to: C) { + var c = from.i + + operator fun next(): C { + val next = C(c) + c++ + return next + } + + operator fun hasNext(): Boolean = c <= to.i +} + +class C(val i : Int) { + operator fun rangeTo(c: C) = Range(this, c) +} + +class M { + operator fun C.component1() = i + 1 + operator fun C.component2() = i + 2 + + fun doTest(): String { + var s = "" + for ((a, b) in C(0)..C(2)) { + s += "$a:$b;" + } + return s + } +} + + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt new file mode 100644 index 00000000000..80258eee8e6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt @@ -0,0 +1,37 @@ +class Range(val from : C, val to: C) { + operator fun iterator() = It(from, to) +} + +class It(val from: C, val to: C) { + var c = from.i + + operator fun next(): C { + val next = C(c) + c++ + return next + } + + operator fun hasNext(): Boolean = c <= to.i +} + +class C(val i : Int) { + operator fun rangeTo(c: C) = Range(this, c) +} + +class M { + operator fun C.component1() = i + 1 + operator fun C.component2() = i + 2 +} + +fun M.doTest(): String { + var s = "" + for ((a, b) in C(0)..C(2)) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/MultiDeclForValCaptured.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/MultiDeclForValCaptured.kt new file mode 100644 index 00000000000..4687822bb09 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/MultiDeclForValCaptured.kt @@ -0,0 +1,34 @@ +class Range(val from : C, val to: C) { + operator fun iterator() = It(from, to) +} + +class It(val from: C, val to: C) { + var c = from.i + + operator fun next(): C { + val next = C(c) + c++ + return next + } + + operator fun hasNext(): Boolean = c <= to.i +} + +class C(val i : Int) { + operator fun component1() = i + 1 + operator fun component2() = i + 2 + operator fun rangeTo(c: C) = Range(this, c) +} + +fun doTest(): String { + var s = "" + for ((a, b) in C(0)..C(2)) { + s += {"$a:$b;"}() + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/UnderscoreNames.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/UnderscoreNames.kt new file mode 100644 index 00000000000..ff9d07f1f46 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/UnderscoreNames.kt @@ -0,0 +1,43 @@ +class Range(val from : C, val to: C) { + operator fun iterator() = It(from, to) +} + +class It(val from: C, val to: C) { + var c = from.i + + operator fun next(): C { + val next = C(c) + c++ + return next + } + + operator fun hasNext(): Boolean = c <= to.i +} + +class C(val i : Int) { + operator fun component1() = i + 1 + operator fun component2() = i + 2 + operator fun rangeTo(c: C) = Range(this, c) +} + +fun doTest(): String { + var s = "" + for ((a, _) in C(0)..C(2)) { + s += "$a;" + } + + for ((_, b) in C(1)..C(3)) { + s += "$b;" + } + + for ((_, `_`) in C(2)..C(4)) { + s += "$_;" + } + + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1;2;3;3;4;5;4;5;6;") "OK" else "fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/UnderscoreNamesDontCallComponent.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/UnderscoreNamesDontCallComponent.kt new file mode 100644 index 00000000000..644125c9809 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/UnderscoreNamesDontCallComponent.kt @@ -0,0 +1,15 @@ +class A { + operator fun component1() = "O" + operator fun component2(): String = throw RuntimeException("fail 0") + operator fun component3() = "K" +} + +fun box(): String { + val aA = Array(1) { A() } + + for ((x, _, z) in aA) { + return x + z + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/MultiDeclFor.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/MultiDeclFor.kt new file mode 100644 index 00000000000..1c746927ffc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/MultiDeclFor.kt @@ -0,0 +1,34 @@ +class Range(val from : C, val to: C) { + operator fun iterator() = It(from, to) +} + +class It(val from: C, val to: C) { + var c = from.i + + operator fun next(): C { + val next = C(c) + c++ + return next + } + + operator fun hasNext(): Boolean = c <= to.i +} + +class C(val i : Int) { + operator fun component1() = i + 1 + operator fun component2() = i + 2 + infix fun rangeTo(c: C) = Range(this, c) +} + +fun doTest(): String { + var s = "" + for ((a, b) in C(0) rangeTo C(2)) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/MultiDeclForComponentExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/MultiDeclForComponentExtensions.kt new file mode 100644 index 00000000000..2a3ce2cf5b7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/MultiDeclForComponentExtensions.kt @@ -0,0 +1,34 @@ +class Range(val from : C, val to: C) { + operator fun iterator() = It(from, to) +} + +class It(val from: C, val to: C) { + var c = from.i + + operator fun next(): C { + val next = C(c) + c++ + return next + } + + operator fun hasNext(): Boolean = c <= to.i +} + +class C(val i : Int) { + infix fun rangeTo(c: C) = Range(this, c) +} +operator fun C.component1() = i + 1 +operator fun C.component2() = i + 2 + +fun doTest(): String { + var s = "" + for ((a, b) in C(0) rangeTo C(2)) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/MultiDeclForComponentMemberExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/MultiDeclForComponentMemberExtensions.kt new file mode 100644 index 00000000000..86973dd8f4f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/MultiDeclForComponentMemberExtensions.kt @@ -0,0 +1,38 @@ +class Range(val from : C, val to: C) { + operator fun iterator() = It(from, to) +} + +class It(val from: C, val to: C) { + var c = from.i + + operator fun next(): C { + val next = C(c) + c++ + return next + } + + operator fun hasNext(): Boolean = c <= to.i +} + +class C(val i : Int) { + operator fun rangeTo(c: C) = Range(this, c) +} + +class M { + operator fun C.component1() = i + 1 + operator fun C.component2() = i + 2 + + fun doTest(): String { + var s = "" + for ((a, b) in C(0).rangeTo(C(2))) { + s += "$a:$b;" + } + return s + } +} + + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt new file mode 100644 index 00000000000..43c353d5735 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt @@ -0,0 +1,37 @@ +class Range(val from : C, val to: C) { + operator fun iterator() = It(from, to) +} + +class It(val from: C, val to: C) { + var c = from.i + + operator fun next(): C { + val next = C(c) + c++ + return next + } + + operator fun hasNext(): Boolean = c <= to.i +} + +class C(val i : Int) { + infix fun rangeTo(c: C) = Range(this, c) +} + +class M { + operator fun C.component1() = i + 1 + operator fun C.component2() = i + 2 +} + +fun M.doTest(): String { + var s = "" + for ((a, b) in C(0) rangeTo C(2)) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/MultiDeclForValCaptured.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/MultiDeclForValCaptured.kt new file mode 100644 index 00000000000..b09acb4b8aa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/MultiDeclForValCaptured.kt @@ -0,0 +1,34 @@ +class Range(val from : C, val to: C) { + operator fun iterator() = It(from, to) +} + +class It(val from: C, val to: C) { + var c = from.i + + operator fun next(): C { + val next = C(c) + c++ + return next + } + + operator fun hasNext(): Boolean = c <= to.i +} + +class C(val i : Int) { + operator fun component1() = i + 1 + operator fun component2() = i + 2 + infix fun rangeTo(c: C) = Range(this, c) +} + +fun doTest(): String { + var s = "" + for ((a, b) in C(0) rangeTo C(2)) { + s += {"$a:$b;"}() + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/int/MultiDeclForComponentExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/int/MultiDeclForComponentExtensions.kt new file mode 100644 index 00000000000..68454565301 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/int/MultiDeclForComponentExtensions.kt @@ -0,0 +1,15 @@ +operator fun Int.component1() = this + 1 +operator fun Int.component2() = this + 2 + +fun doTest(): String { + var s = "" + for ((a, b) in 0.rangeTo(2)) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/int/MultiDeclForComponentExtensionsValCaptured.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/int/MultiDeclForComponentExtensionsValCaptured.kt new file mode 100644 index 00000000000..f1d711a42e2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/int/MultiDeclForComponentExtensionsValCaptured.kt @@ -0,0 +1,15 @@ +operator fun Int.component1() = this + 1 +operator fun Int.component2() = this + 2 + +fun doTest(): String { + var s = "" + for ((a, b) in 0.rangeTo(2)) { + s += {"$a:$b;"}() + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/int/MultiDeclForComponentMemberExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/int/MultiDeclForComponentMemberExtensions.kt new file mode 100644 index 00000000000..b5cade5f662 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/int/MultiDeclForComponentMemberExtensions.kt @@ -0,0 +1,17 @@ +class M { + operator fun Int.component1() = this + 1 + operator fun Int.component2() = this + 2 + + fun doTest(): String { + var s = "" + for ((a, b) in 0.rangeTo(2)) { + s += "$a:$b;" + } + return s + } +} + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/int/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/int/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt new file mode 100644 index 00000000000..22ed58c8d10 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/int/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt @@ -0,0 +1,17 @@ +class M { + operator fun Int.component1() = this + 1 + operator fun Int.component2() = this + 2 +} + +fun M.doTest(): String { + var s = "" + for ((a, b) in 0.rangeTo(2)) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/long/MultiDeclForComponentExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/long/MultiDeclForComponentExtensions.kt new file mode 100644 index 00000000000..132c532501f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/long/MultiDeclForComponentExtensions.kt @@ -0,0 +1,15 @@ +operator fun Long.component1() = this + 1 +operator fun Long.component2() = this + 2 + +fun doTest(): String { + var s = "" + for ((a, b) in 0.toLong().rangeTo(2.toLong())) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/long/MultiDeclForComponentExtensionsValCaptured.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/long/MultiDeclForComponentExtensionsValCaptured.kt new file mode 100644 index 00000000000..fcb229e7f75 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/long/MultiDeclForComponentExtensionsValCaptured.kt @@ -0,0 +1,15 @@ +operator fun Long.component1() = this + 1 +operator fun Long.component2() = this + 2 + +fun doTest(): String { + var s = "" + for ((a, b) in 0.toLong().rangeTo(2.toLong())) { + s += {"$a:$b;"}() + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/long/MultiDeclForComponentMemberExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/long/MultiDeclForComponentMemberExtensions.kt new file mode 100644 index 00000000000..664233c2d14 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/long/MultiDeclForComponentMemberExtensions.kt @@ -0,0 +1,17 @@ +class M { + operator fun Long.component1() = this + 1 + operator fun Long.component2() = this + 2 + + fun doTest(): String { + var s = "" + for ((a, b) in 0.toLong().rangeTo(2.toLong())) { + s += "$a:$b;" + } + return s + } +} + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/long/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/long/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt new file mode 100644 index 00000000000..99e71d259f3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeTo/long/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt @@ -0,0 +1,17 @@ +class M { + operator fun Long.component1() = this + 1 + operator fun Long.component2() = this + 2 +} + +fun M.doTest(): String { + var s = "" + for ((a, b) in 0.toLong().rangeTo(2.toLong())) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/MultiDeclFor.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/MultiDeclFor.kt new file mode 100644 index 00000000000..be1dacd3f39 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/MultiDeclFor.kt @@ -0,0 +1,34 @@ +class Range(val from : C, val to: C) { + operator fun iterator() = It(from, to) +} + +class It(val from: C, val to: C) { + var c = from.i + + operator fun next(): C { + val next = C(c) + c++ + return next + } + + operator fun hasNext(): Boolean = c <= to.i +} + +class C(val i : Int) { + operator fun component1() = i + 1 + operator fun component2() = i + 2 + fun rangeTo(c: C) = Range(this, c) +} + +fun doTest(): String { + var s = "" + for ((a, b) in C(0).rangeTo(C(2))) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/MultiDeclForComponentExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/MultiDeclForComponentExtensions.kt new file mode 100644 index 00000000000..08eb7d8914d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/MultiDeclForComponentExtensions.kt @@ -0,0 +1,34 @@ +class Range(val from : C, val to: C) { + operator fun iterator() = It(from, to) +} + +class It(val from: C, val to: C) { + var c = from.i + + operator fun next(): C { + val next = C(c) + c++ + return next + } + + operator fun hasNext(): Boolean = c <= to.i +} + +class C(val i : Int) { + fun rangeTo(c: C) = Range(this, c) +} +operator fun C.component1() = i + 1 +operator fun C.component2() = i + 2 + +fun doTest(): String { + var s = "" + for ((a, b) in C(0).rangeTo(C(2))) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/MultiDeclForComponentMemberExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/MultiDeclForComponentMemberExtensions.kt new file mode 100644 index 00000000000..1efc37832ab --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/MultiDeclForComponentMemberExtensions.kt @@ -0,0 +1,38 @@ +class Range(val from : C, val to: C) { + operator fun iterator() = It(from, to) +} + +class It(val from: C, val to: C) { + var c = from.i + + operator fun next(): C { + val next = C(c) + c++ + return next + } + + operator fun hasNext(): Boolean = c <= to.i +} + +class C(val i : Int) { + fun rangeTo(c: C) = Range(this, c) +} + +class M { + operator fun C.component1() = i + 1 + operator fun C.component2() = i + 2 + + fun doTest(): String { + var s = "" + for ((a, b) in C(0).rangeTo(C(2))) { + s += "$a:$b;" + } + return s + } +} + + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt new file mode 100644 index 00000000000..7daff02f89c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt @@ -0,0 +1,37 @@ +class Range(val from : C, val to: C) { + operator fun iterator() = It(from, to) +} + +class It(val from: C, val to: C) { + var c = from.i + + operator fun next(): C { + val next = C(c) + c++ + return next + } + + operator fun hasNext(): Boolean = c <= to.i +} + +class C(val i : Int) { + fun rangeTo(c: C) = Range(this, c) +} + +class M { + operator fun C.component1() = i + 1 + operator fun C.component2() = i + 2 +} + +fun M.doTest(): String { + var s = "" + for ((a, b) in C(0).rangeTo(C(2))) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/MultiDeclForValCaptured.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/MultiDeclForValCaptured.kt new file mode 100644 index 00000000000..8df7e251bf5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/MultiDeclForValCaptured.kt @@ -0,0 +1,34 @@ +class Range(val from : C, val to: C) { + operator fun iterator() = It(from, to) +} + +class It(val from: C, val to: C) { + var c = from.i + + operator fun next(): C { + val next = C(c) + c++ + return next + } + + operator fun hasNext(): Boolean = c <= to.i +} + +class C(val i : Int) { + operator fun component1() = i + 1 + operator fun component2() = i + 2 + fun rangeTo(c: C) = Range(this, c) +} + +fun doTest(): String { + var s = "" + for ((a, b) in C(0).rangeTo(C(2))) { + s += {"$a:$b;"}() + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/int/MultiDeclForComponentExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/int/MultiDeclForComponentExtensions.kt new file mode 100644 index 00000000000..68454565301 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/int/MultiDeclForComponentExtensions.kt @@ -0,0 +1,15 @@ +operator fun Int.component1() = this + 1 +operator fun Int.component2() = this + 2 + +fun doTest(): String { + var s = "" + for ((a, b) in 0.rangeTo(2)) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/int/MultiDeclForComponentExtensionsValCaptured.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/int/MultiDeclForComponentExtensionsValCaptured.kt new file mode 100644 index 00000000000..f1d711a42e2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/int/MultiDeclForComponentExtensionsValCaptured.kt @@ -0,0 +1,15 @@ +operator fun Int.component1() = this + 1 +operator fun Int.component2() = this + 2 + +fun doTest(): String { + var s = "" + for ((a, b) in 0.rangeTo(2)) { + s += {"$a:$b;"}() + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/int/MultiDeclForComponentMemberExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/int/MultiDeclForComponentMemberExtensions.kt new file mode 100644 index 00000000000..b5cade5f662 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/int/MultiDeclForComponentMemberExtensions.kt @@ -0,0 +1,17 @@ +class M { + operator fun Int.component1() = this + 1 + operator fun Int.component2() = this + 2 + + fun doTest(): String { + var s = "" + for ((a, b) in 0.rangeTo(2)) { + s += "$a:$b;" + } + return s + } +} + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/int/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/int/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt new file mode 100644 index 00000000000..22ed58c8d10 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/int/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt @@ -0,0 +1,17 @@ +class M { + operator fun Int.component1() = this + 1 + operator fun Int.component2() = this + 2 +} + +fun M.doTest(): String { + var s = "" + for ((a, b) in 0.rangeTo(2)) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentExtensions.kt new file mode 100644 index 00000000000..c8bc4ce6e61 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentExtensions.kt @@ -0,0 +1,23 @@ +fun f(l : Long) { + l.rangeTo(l) +} +fun box(): String { + return "OK" +} + + +//operator fun Long.component1() = this + 1 +//operator fun Long.component2() = this + 2 +// +//fun doTest(): String { +// var s = "" +// for ((a, b) in 0.toLong().rangeTo(2.toLong())) { +// s += "$a:$b;" +// } +// return s +//} +// +//fun box(): String { +// val s = doTest() +// return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +//} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentExtensionsValCaptured.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentExtensionsValCaptured.kt new file mode 100644 index 00000000000..fcb229e7f75 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentExtensionsValCaptured.kt @@ -0,0 +1,15 @@ +operator fun Long.component1() = this + 1 +operator fun Long.component2() = this + 2 + +fun doTest(): String { + var s = "" + for ((a, b) in 0.toLong().rangeTo(2.toLong())) { + s += {"$a:$b;"}() + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentMemberExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentMemberExtensions.kt new file mode 100644 index 00000000000..664233c2d14 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentMemberExtensions.kt @@ -0,0 +1,17 @@ +class M { + operator fun Long.component1() = this + 1 + operator fun Long.component2() = this + 2 + + fun doTest(): String { + var s = "" + for ((a, b) in 0.toLong().rangeTo(2.toLong())) { + s += "$a:$b;" + } + return s + } +} + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt new file mode 100644 index 00000000000..99e71d259f3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt @@ -0,0 +1,17 @@ +class M { + operator fun Long.component1() = this + 1 + operator fun Long.component2() = this + 2 +} + +fun M.doTest(): String { + var s = "" + for ((a, b) in 0.toLong().rangeTo(2.toLong())) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/int/MultiDeclForComponentExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/int/MultiDeclForComponentExtensions.kt new file mode 100644 index 00000000000..5f60ba33287 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/int/MultiDeclForComponentExtensions.kt @@ -0,0 +1,15 @@ +operator fun Int.component1() = this + 1 +operator fun Int.component2() = this + 2 + +fun doTest(): String { + var s = "" + for ((a, b) in 0..2) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/int/MultiDeclForComponentExtensionsValCaptured.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/int/MultiDeclForComponentExtensionsValCaptured.kt new file mode 100644 index 00000000000..fd0f6dac885 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/int/MultiDeclForComponentExtensionsValCaptured.kt @@ -0,0 +1,15 @@ +operator fun Int.component1() = this + 1 +operator fun Int.component2() = this + 2 + +fun doTest(): String { + var s = "" + for ((a, b) in 0..2) { + s += {"$a:$b;"}() + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/int/MultiDeclForComponentMemberExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/int/MultiDeclForComponentMemberExtensions.kt new file mode 100644 index 00000000000..e1a6673c11a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/int/MultiDeclForComponentMemberExtensions.kt @@ -0,0 +1,17 @@ +class M { + operator fun Int.component1() = this + 1 + operator fun Int.component2() = this + 2 + + fun doTest(): String { + var s = "" + for ((a, b) in 0..2) { + s += "$a:$b;" + } + return s + } +} + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/int/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/int/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt new file mode 100644 index 00000000000..1a20e756f0f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/int/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt @@ -0,0 +1,17 @@ +class M { + operator fun Int.component1() = this + 1 + operator fun Int.component2() = this + 2 +} + +fun M.doTest(): String { + var s = "" + for ((a, b) in 0..2) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/long/MultiDeclForComponentExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/long/MultiDeclForComponentExtensions.kt new file mode 100644 index 00000000000..85f78eabcdc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/long/MultiDeclForComponentExtensions.kt @@ -0,0 +1,15 @@ +operator fun Long.component1() = this + 1 +operator fun Long.component2() = this + 2 + +fun doTest(): String { + var s = "" + for ((a, b) in 0.toLong()..2.toLong()) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/long/MultiDeclForComponentExtensionsValCaptured.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/long/MultiDeclForComponentExtensionsValCaptured.kt new file mode 100644 index 00000000000..8bf72ec08d7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/long/MultiDeclForComponentExtensionsValCaptured.kt @@ -0,0 +1,15 @@ +operator fun Long.component1() = this + 1 +operator fun Long.component2() = this + 2 + +fun doTest(): String { + var s = "" + for ((a, b) in 0.toLong()..2.toLong()) { + s += {"$a:$b;"}() + } + return s +} + +fun box(): String { + val s = doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/long/MultiDeclForComponentMemberExtensions.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/long/MultiDeclForComponentMemberExtensions.kt new file mode 100644 index 00000000000..a11156329f4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/long/MultiDeclForComponentMemberExtensions.kt @@ -0,0 +1,17 @@ +class M { + operator fun Long.component1() = this + 1 + operator fun Long.component2() = this + 2 + + fun doTest(): String { + var s = "" + for ((a, b) in 0.toLong()..2.toLong()) { + s += "$a:$b;" + } + return s + } +} + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/long/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/long/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt new file mode 100644 index 00000000000..3ee641f67f7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/forRange/long/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt @@ -0,0 +1,17 @@ +class M { + operator fun Long.component1() = this + 1 + operator fun Long.component2() = this + 2 +} + +fun M.doTest(): String { + var s = "" + for ((a, b) in 0.toLong()..2.toLong()) { + s += "$a:$b;" + } + return s +} + +fun box(): String { + val s = M().doTest() + return if (s == "1:2;2:3;3:4;") "OK" else "fail: $s" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/kt9828_hashMap.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/kt9828_hashMap.kt new file mode 100644 index 00000000000..8793aef1b14 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/kt9828_hashMap.kt @@ -0,0 +1,11 @@ +// WITH_RUNTIME + +fun box(): String { + val hashMap = HashMap() + hashMap.put("one", 1) + hashMap.put("two", 2) + for ((key, value) in hashMap) { + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/multiDecl/returnInElvis.kt b/backend.native/tests/external/codegen/blackbox/multiDecl/returnInElvis.kt new file mode 100644 index 00000000000..9f381d75225 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multiDecl/returnInElvis.kt @@ -0,0 +1,22 @@ +data class Z(val p: String, val k: String) + + +fun create(p: Boolean): Z? { + return if (p) { + Z("O", "K") + } + else { + null; + } +} + +fun test(p: Boolean): String { + val (a, b) = create(p) ?: return "null" + return a + b +} + +fun box(): String { + if (test(false) != "null") return "fail 1: ${test(false)}" + + return test(true) +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/callMultifileClassMemberFromOtherPackage.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/callMultifileClassMemberFromOtherPackage.kt new file mode 100644 index 00000000000..7cd4b20c224 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/callMultifileClassMemberFromOtherPackage.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: box.kt + +package test + +import b.bar + +fun box(): String = bar() + +// FILE: caller.kt + +package b + +import a.foo + +fun bar(): String = foo() + +// FILE: multifileClass.kt + +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +fun foo(): String = "OK" diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/callsToMultifileClassFromOtherPackage.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/callsToMultifileClassFromOtherPackage.kt new file mode 100644 index 00000000000..ab7a0ca4c7b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/callsToMultifileClassFromOtherPackage.kt @@ -0,0 +1,27 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: 1.kt + +import a.* + +fun box(): String { + if (foo() != "OK") return "Fail function" + if (constOK != "OK") return "Fail const" + if (valOK != "OK") return "Fail val" + varOK = "OK" + if (varOK != "OK") return "Fail var" + + return "OK" +} + +// FILE: 2.kt + +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +fun foo(): String = "OK" +const val constOK: String = "OK" +val valOK: String = "OK" +var varOK: String = "Hmmm?" diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/constPropertyReferenceFromMultifileClass.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/constPropertyReferenceFromMultifileClass.kt new file mode 100644 index 00000000000..42325c35b6b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/constPropertyReferenceFromMultifileClass.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: 1.kt + +import a.OK + +fun box(): String { + val okRef = ::OK + + val annotations = okRef.annotations + if (annotations.size != 1) { + return "Failed, annotations: $annotations" + } + + return okRef.get() +} + +// FILE: 2.kt + +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +annotation class A + +@A +const val OK: String = "OK" diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/inlineMultifileClassMemberFromOtherPackage.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/inlineMultifileClassMemberFromOtherPackage.kt new file mode 100644 index 00000000000..9c4f2986c24 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/inlineMultifileClassMemberFromOtherPackage.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: box.kt + +package test + +import a.foo + +fun box(): String = foo { "OK" } + +// FILE: foo.kt + +@file:[JvmName("A") JvmMultifileClass] +package a + +inline fun foo(body: () -> String): String = zee(body()) + +// FILE: zee.kt + +@file:[JvmName("A") JvmMultifileClass] +package a + +public fun zee(x: String): String = x diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/multifileClassPartsInitialization.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/multifileClassPartsInitialization.kt new file mode 100644 index 00000000000..9330fc66d66 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/multifileClassPartsInitialization.kt @@ -0,0 +1,38 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: box.kt + +import a.* + +fun box(): String = OK + +// FILE: part1.kt + +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +val O: String = "O" + +// FILE: part2.kt + +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +val K: String = "K" + +// FILE: part3.kt + +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +val OK: String = O + K + +// FILE: irrelevant.kt + +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +val X: Nothing = throw AssertionError("X should not be initialized") + diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/multifileClassWith2Files.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/multifileClassWith2Files.kt new file mode 100644 index 00000000000..0f37394e747 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/multifileClassWith2Files.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Baz.java + +public class Baz { + public static String baz() { + return Util.foo() + Util.bar(); + } +} + +// FILE: bar.kt + +@file:JvmName("Util") +@file:JvmMultifileClass +public fun bar(): String = "K" + +// FILE: foo.kt + +@file:[JvmName("Util") JvmMultifileClass] +public fun foo(): String = "O" + +// FILE: test.kt + +fun box(): String = Baz.baz() diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/multifileClassWithCrossCall.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/multifileClassWithCrossCall.kt new file mode 100644 index 00000000000..97c9fc9e7c5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/multifileClassWithCrossCall.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Baz.java + +public class Baz { + public static String baz() { + return Util.foo() + Util.bar(); + } +} + +// FILE: bar.kt + +@file:JvmName("Util") +@file:JvmMultifileClass +public fun bar(): String = barx() + +public fun foox(): String = "O" + +// FILE: foo.kt + +@file:JvmName("Util") +@file:JvmMultifileClass +public fun foo(): String = foox() + +public fun barx(): String = "K" + +// FILE: test.kt + +fun box(): String = Baz.baz() diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/multifileClassWithPrivate.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/multifileClassWithPrivate.kt new file mode 100644 index 00000000000..2031d15fa4e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/multifileClassWithPrivate.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Baz.java + +public class Baz { + public static String baz() { + return Util.foo() + Util.bar(); + } +} + +// FILE: bar.kt + +@file:JvmName("Util") +@file:JvmMultifileClass +public fun bar(): String = barx() + +private fun barx(): String = "K" + +// FILE: foo.kt + +@file:JvmName("Util") +@file:JvmMultifileClass +public fun foo(): String = foox() + +private fun foox(): String = "O" + +// FILE: test.kt + +fun box(): String = Baz.baz() diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/callableRefToFun.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/callableRefToFun.kt new file mode 100644 index 00000000000..02986a391d6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/callableRefToFun.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// KOTLIN_CONFIGURATION_FLAGS: +JVM.INHERIT_MULTIFILE_PARTS +// FILE: box.kt + +import a.* + +fun box(): String = (::ok)() + +// FILE: part1.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +fun ok() = "OK" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/callableRefToInternalValInline.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/callableRefToInternalValInline.kt new file mode 100644 index 00000000000..5dcf224f877 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/callableRefToInternalValInline.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// KOTLIN_CONFIGURATION_FLAGS: +JVM.INHERIT_MULTIFILE_PARTS +// FILE: box.kt + +import a.* + +fun box(): String = okInline() + +// FILE: part1.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +internal val ok = run { "OK" } + +internal inline fun okInline() = + ::ok.get() \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/callableRefToPrivateVal.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/callableRefToPrivateVal.kt new file mode 100644 index 00000000000..90d6548b41a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/callableRefToPrivateVal.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// KOTLIN_CONFIGURATION_FLAGS: +JVM.INHERIT_MULTIFILE_PARTS +// FILE: box.kt + +import a.* + +fun box(): String = OK.okRef.get() + +// FILE: part1.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +private val ok = run { "OK" } + +object OK { + val okRef = ::ok +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/callableRefToVal.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/callableRefToVal.kt new file mode 100644 index 00000000000..957059f5e0c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/callableRefToVal.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// KOTLIN_CONFIGURATION_FLAGS: +JVM.INHERIT_MULTIFILE_PARTS +// FILE: box.kt + +import a.* + +fun box(): String = ::OK.get() + +// FILE: part1.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +val OK = run { "OK" } \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/calls.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/calls.kt new file mode 100644 index 00000000000..3aa873305fe --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/calls.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// KOTLIN_CONFIGURATION_FLAGS: +JVM.INHERIT_MULTIFILE_PARTS +// FILE: Baz.java + +public class Baz { + public static String baz() { + return Util.foo() + Util.bar(); + } +} + +// FILE: bar.kt + +@file:JvmName("Util") +@file:JvmMultifileClass +public fun bar(): String = barx() + +public fun foox(): String = "O" + +// FILE: foo.kt + +@file:JvmName("Util") +@file:JvmMultifileClass +public fun foo(): String = foox() + +public fun barx(): String = "K" + +// FILE: test.kt + +fun box(): String = Baz.baz() diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/deferredStaticInitialization.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/deferredStaticInitialization.kt new file mode 100644 index 00000000000..f337388e48f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/deferredStaticInitialization.kt @@ -0,0 +1,42 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// KOTLIN_CONFIGURATION_FLAGS: +JVM.INHERIT_MULTIFILE_PARTS +// FILE: box.kt + +import a.* + +fun box(): String = OK + +// FILE: part1.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +val O = run { "O" } + +// FILE: part2.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +const val K = "K" + +// FILE: part3.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +val OK: String = run { O + K } + +// FILE: irrelevantPart.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +val X1: Nothing = + throw AssertionError("X1 should not be initialized") + +// FILE: reallyIrrelevantPart.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +val X2: Nothing = + throw AssertionError("X2 should not be initialized") \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/delegatedVal.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/delegatedVal.kt new file mode 100644 index 00000000000..c5f8e05ae05 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/delegatedVal.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// KOTLIN_CONFIGURATION_FLAGS: +JVM.INHERIT_MULTIFILE_PARTS +// FILE: box.kt + +import a.* + +fun box(): String = OK + +// FILE: part1.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +val OK: String by lazy { "OK" } \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/initializePrivateVal.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/initializePrivateVal.kt new file mode 100644 index 00000000000..3e6fc5d5367 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/initializePrivateVal.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// KOTLIN_CONFIGURATION_FLAGS: +JVM.INHERIT_MULTIFILE_PARTS +// FILE: box.kt + +import a.* + +fun box(): String = ok() + +// FILE: part1.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +private val OK = run { "OK" } + +fun ok() = OK \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/initializePublicVal.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/initializePublicVal.kt new file mode 100644 index 00000000000..4eea8f704f6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/initializePublicVal.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// KOTLIN_CONFIGURATION_FLAGS: +JVM.INHERIT_MULTIFILE_PARTS +// FILE: box.kt + +import a.* + +fun box(): String = OK + +// FILE: part1.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +public val OK = run { "OK" } diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/overlappingFuns.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/overlappingFuns.kt new file mode 100644 index 00000000000..8c37f0c014c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/overlappingFuns.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// KOTLIN_CONFIGURATION_FLAGS: +JVM.INHERIT_MULTIFILE_PARTS +// FILE: box.kt + +import a.* + +fun box(): String = ok() + +// FILE: part1.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +private fun overlapping() = "oops #1" + +// FILE: part2.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +private fun overlapping() = "OK" + +fun ok() = overlapping() + +// FILE: part3.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +private fun overlapping() = "oops #2" diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/overlappingVals.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/overlappingVals.kt new file mode 100644 index 00000000000..40a4f14a0c4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/overlappingVals.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// KOTLIN_CONFIGURATION_FLAGS: +JVM.INHERIT_MULTIFILE_PARTS +// FILE: box.kt + +import a.* + +fun box(): String = ok() + +// FILE: part1.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +private val overlapping = run { "oops #1" } + +// FILE: part2.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +private val overlapping = run { "OK" } + +fun ok() = overlapping + +// FILE: part3.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +private val overlapping = run { "oops #2" } diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/valAccessFromInlineFunCalledFromJava.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/valAccessFromInlineFunCalledFromJava.kt new file mode 100644 index 00000000000..4720dcc5287 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/valAccessFromInlineFunCalledFromJava.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// KOTLIN_CONFIGURATION_FLAGS: +JVM.INHERIT_MULTIFILE_PARTS +// FILE: box.kt + +import a.* + +fun box(): String = J.ok() + +// FILE: part1.kt +@file:[JvmName("MC") JvmMultifileClass] +package a + +val O = run { "O" } +const val K = "K" + +inline fun ok(): String { + return O + K +} + +// FILE: J.java +import a.MC; + +public class J { + public static String ok() { + return MC.ok(); + } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/valAccessFromInlinedToDifferentPackage.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/valAccessFromInlinedToDifferentPackage.kt new file mode 100644 index 00000000000..8946cb730ba --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/valAccessFromInlinedToDifferentPackage.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// KOTLIN_CONFIGURATION_FLAGS: +JVM.INHERIT_MULTIFILE_PARTS +// FILE: box.kt + +import a.* + +fun box(): String = ok {} + +// FILE: part1.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +val O = run { "O" } +const val K = "K" + +inline fun ok(block: () -> Unit): String { + block() + return O + K +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/valWithAccessor.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/valWithAccessor.kt new file mode 100644 index 00000000000..8be860d7253 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/optimized/valWithAccessor.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// KOTLIN_CONFIGURATION_FLAGS: +JVM.INHERIT_MULTIFILE_PARTS +// FILE: box.kt + +import a.* + +fun box(): String = OK().ok + +// FILE: part1.kt +@file:[JvmName("MultifileClass") JvmMultifileClass] +package a + +private val reallyOk = run { "OK" } + +class OK() { + val ok = reallyOk +} diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/privateConstVal.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/privateConstVal.kt new file mode 100644 index 00000000000..141fdc945f5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/privateConstVal.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: foo.kt +@file:JvmName("Util") +@file:JvmMultifileClass +package test + +private const val x = "O" + +fun foo() = x + +// FILE: bar.kt +@file:JvmName("Util") +@file:JvmMultifileClass +package test + +private const val x = "K" + +fun bar() = x + +// FILE: test.kt +package test + +fun box(): String = foo() + bar() \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/multifileClasses/samePartNameDifferentFacades.kt b/backend.native/tests/external/codegen/blackbox/multifileClasses/samePartNameDifferentFacades.kt new file mode 100644 index 00000000000..73abfb3602b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/multifileClasses/samePartNameDifferentFacades.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: 1/part.kt + +@file:JvmName("Foo") +@file:JvmMultifileClass +package test + +fun foo(): String = "O" + +// FILE: 2/part.kt + +@file:JvmName("Bar") +@file:JvmMultifileClass +package test + +fun bar(): String = "K" + +// FILE: box.kt + +package test + +fun box(): String = foo() + bar() diff --git a/backend.native/tests/external/codegen/blackbox/nonLocalReturns/kt6895.kt b/backend.native/tests/external/codegen/blackbox/nonLocalReturns/kt6895.kt new file mode 100644 index 00000000000..4e6fb1160a6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/nonLocalReturns/kt6895.kt @@ -0,0 +1,26 @@ +// TARGET_BACKEND: JVM + +// WITH_RUNTIME + +import java.util.concurrent.locks.ReentrantReadWriteLock +import kotlin.concurrent.write + +class UpdateableThing { + private val lock = ReentrantReadWriteLock() + private var updateCount = 0 + + fun performUpdates(block: () -> T): T { + lock.write { + ++updateCount + val result = block() + --updateCount + + return result + } + } +} + + +fun box(): String { + return UpdateableThing().performUpdates { "OK" } +} diff --git a/backend.native/tests/external/codegen/blackbox/nonLocalReturns/kt9644let.kt b/backend.native/tests/external/codegen/blackbox/nonLocalReturns/kt9644let.kt new file mode 100644 index 00000000000..2972f593a56 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/nonLocalReturns/kt9644let.kt @@ -0,0 +1,12 @@ +// WITH_RUNTIME + +fun foo() { + with(1) { + return (1..2).forEach { it } + } +} + +fun box(): String { + foo() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/nonLocalReturns/use.kt b/backend.native/tests/external/codegen/blackbox/nonLocalReturns/use.kt new file mode 100644 index 00000000000..4c6934a5ebf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/nonLocalReturns/use.kt @@ -0,0 +1,177 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import java.io.Closeable + +class MyException(message: String) : Exception(message) + +class Holder(var value: String) { + operator fun plusAssign(s: String?) { + value += s + if (s != "closed") { + value += "->" + } + } +} + +class TestLocal() : Closeable { + + var status = Holder("") + + private fun underMutexFun() { + status += "called" + } + + fun local(): Holder { + use { + underMutexFun() + } + return status + } + + + fun nonLocalSimple(): Holder { + use { + underMutexFun() + return status + } + return Holder("fail") + } + + fun nonLocalWithException(): Holder { + use { + try { + underMutexFun() + throw MyException("exception") + } catch (e: MyException) { + status += e.message!! + return status + } + } + return Holder("fail") + } + + fun nonLocalWithFinally(): Holder { + use { + try { + underMutexFun() + return Holder("fail") + } finally { + status += "finally" + return status + } + } + return Holder("fail") + } + + fun nonLocalWithExceptionAndFinally(): Holder { + use { + try { + underMutexFun() + throw MyException("exception") + } catch (e: MyException) { + status += e.message + return status + } finally { + status += "finally" + } + } + return Holder("fail") + } + + fun nonLocalWithExceptionAndFinallyWithReturn(): Holder { + use { + try { + underMutexFun() + throw MyException("exception") + } catch (e: MyException) { + status += e.message + return Holder("fail") + } finally { + status += "finally" + return status + } + } + return Holder("fail") + } + + fun nonLocalNestedWithException(): Holder { + use { + try { + try { + underMutexFun() + throw MyException("exception") + } catch (e: MyException) { + status += "exception" + return Holder("fail") + } finally { + status += "finally1" + return status + } + } finally { + status += "finally2" + } + } + return Holder("fail") + } + + fun nonLocalNestedFinally(): Holder { + use { + try { + try { + underMutexFun() + return status + } finally { + status += "finally1" + status + } + } finally { + status += "finally2" + } + } + return Holder("fail") + } + + override fun close() { + status += "closed" + } +} + +fun box(): String { + var callable = TestLocal() + var result = callable.local() + if (result.value != "called->closed") return "fail local: " + result.value + + callable = TestLocal() + result = callable.nonLocalSimple() + if (result.value != "called->closed") return "fail nonLocalSimple: " + result.value + + callable = TestLocal() + result = callable.nonLocalWithException() + if (result.value != "called->exception->closed") return "fail nonLocalWithException: " + result.value + + callable = TestLocal() + result = callable.nonLocalWithFinally() + if (result.value != "called->finally->closed") return "fail nonLocalWithFinally: " + result.value + + callable = TestLocal() + result = callable.nonLocalWithExceptionAndFinally() + if (result.value != "called->exception->finally->closed") return "fail nonLocalWithExceptionAndFinally: " + result.value + + callable = TestLocal() + result = callable.nonLocalWithExceptionAndFinallyWithReturn() + if (result.value != "called->exception->finally->closed") return "fail nonLocalWithExceptionAndFinallyWithReturn: " + result.value + + callable = TestLocal() + result = callable.nonLocalNestedWithException() + if (result.value != "called->exception->finally1->finally2->closed") return "fail nonLocalNestedWithException: " + result.value + + callable = TestLocal() + result = callable.nonLocalNestedFinally() + if (result.value != "called->finally1->finally2->closed") return "fail nonLocalNestedFinally: " + result.value + + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/nonLocalReturns/useWithException.kt b/backend.native/tests/external/codegen/blackbox/nonLocalReturns/useWithException.kt new file mode 100644 index 00000000000..f3bb63dc008 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/nonLocalReturns/useWithException.kt @@ -0,0 +1,190 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import java.io.Closeable +import kotlin.test.assertTrue +import kotlin.test.fail +import kotlin.test.assertEquals + +class MyException(message: String) : Exception(message) + +class Holder(var value: String) { + operator fun plusAssign(s: String?) { + value += s + if (s != "closed") { + value += "->" + } + } +} + +class TestLocal() : Closeable { + + var status = Holder("") + + private fun underMutexFun() { + status += "called" + } + + fun local(): Holder { + use { + underMutexFun() + } + return status + } + + + fun nonLocalSimple(): Holder { + use { + underMutexFun() + return status + } + return Holder("fail") + } + + fun nonLocalWithException(): Holder { + use { + try { + underMutexFun() + throw MyException("exception") + } catch (e: MyException) { + status += e.message!! + return status + } + } + return Holder("fail") + } + + fun nonLocalWithFinally(): Holder { + use { + try { + underMutexFun() + return Holder("fail") + } finally { + status += "finally" + return status + } + } + return Holder("fail") + } + + fun nonLocalWithExceptionAndFinally(): Holder { + use { + try { + underMutexFun() + throw MyException("exception") + } catch (e: MyException) { + status += e.message + return status + } finally { + status += "finally" + } + } + return Holder("fail") + } + + fun nonLocalWithExceptionAndFinallyWithReturn(): Holder { + use { + try { + underMutexFun() + throw MyException("exception") + } catch (e: MyException) { + status += e.message + return Holder("fail") + } finally { + status += "finally" + return status + } + } + return Holder("fail") + } + + fun nonLocalNestedWithException(): Holder { + use { + try { + try { + underMutexFun() + throw MyException("exception") + } catch (e: MyException) { + status += "exception" + return Holder("fail") + } finally { + status += "finally1" + return status + } + } finally { + status += "finally2" + } + } + return Holder("fail") + } + + fun nonLocalNestedFinally(): Holder { + use { + try { + try { + underMutexFun() + return status + } finally { + status += "finally1" + status + } + } finally { + status += "finally2" + } + } + return Holder("fail") + } + + override fun close() { + status += "closed" + throw MyException("error") + } +} + +fun box(): String { + assertError(1,"called->closed") { + local() + } + + assertError(2, "called->closed") { + nonLocalSimple() + } + + assertError(3, "called->exception->closed") { + nonLocalWithException() + } + + assertError(4, "called->finally->closed") { + nonLocalWithFinally() + } + + assertError(5, "called->exception->finally->closed") { + nonLocalWithExceptionAndFinally() + } + + assertError(6, "called->exception->finally->closed") { + nonLocalWithExceptionAndFinallyWithReturn() + } + + assertError(7, "called->exception->finally1->finally2->closed") { + nonLocalNestedWithException() + } + + assertError(8, "called->finally1->finally2->closed") { + nonLocalNestedFinally() + } + + return "OK" +} + +public fun assertError(index: Int, expected: String, l: TestLocal.()->Unit) { + val testLocal = TestLocal() + try { + testLocal.l() + fail("fail $index: no error") + } catch (e: Exception) { + assertEquals(expected, testLocal.status.value, "failed on $index") + } +} diff --git a/backend.native/tests/external/codegen/blackbox/objectIntrinsics/objects.kt b/backend.native/tests/external/codegen/blackbox/objectIntrinsics/objects.kt new file mode 100644 index 00000000000..3eddefd5794 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objectIntrinsics/objects.kt @@ -0,0 +1,94 @@ +package foo + +fun box(): String { + try { + testCompanionObjectAccess() + testInCall() + testDoubleConstants() + testFloatConstants() + testLocalFun() + testTopLevelFun() + testVarTopField() + } + catch (e: Throwable) { + return "Error: \n" + e + } + + return "OK" +} + +fun testCompanionObjectAccess() { + val i = Int + val d = Double + val f = Float + val l = Long + val sh = Short + val b = Byte + val ch = Char + val st = String + val en = Enum +} + +fun testInCall() { + test(Int) + test(Double) + test(Float) + test(Long) + test(Short) + test(Byte) + test(Char) + test(String) + test(Enum) +} + +fun testDoubleConstants() { + val pi = Double.POSITIVE_INFINITY + val ni = Double.NEGATIVE_INFINITY + val nan = Double.NaN + + myAssertEquals(pi, Double.POSITIVE_INFINITY) + myAssertEquals(ni, Double.NEGATIVE_INFINITY) +} + +fun testFloatConstants() { + val pi = Float.POSITIVE_INFINITY + val ni = Float.NEGATIVE_INFINITY + val nan = Float.NaN + + myAssertEquals(pi, Float.POSITIVE_INFINITY) + myAssertEquals(ni, Float.NEGATIVE_INFINITY) +} + +fun testLocalFun() { + fun Int.Companion.LocalFun() : String = "LocalFun" + myAssertEquals("LocalFun", Int.LocalFun()) +} + +fun testTopLevelFun() { + myAssertEquals("TopFun", Int.TopFun()) +} + +fun testVarTopField() { + myAssertEquals(0, Int.TopField) + + Int.TopField++ + myAssertEquals(1, Int.TopField) + + Int.TopField += 5 + myAssertEquals(6, Int.TopField) +} + +fun test(a: Any) {} + +var _field: Int = 0 +var Int.Companion.TopField : Int + get() = _field + set(value) { _field = value }; + +fun Int.Companion.TopFun() : String = "TopFun" + +fun myAssertEquals(a: T, b: T) { + if (a != b) throw Exception("$a != $b") +} + + diff --git a/backend.native/tests/external/codegen/blackbox/objects/anonymousObjectPropertyInitialization.kt b/backend.native/tests/external/codegen/blackbox/objects/anonymousObjectPropertyInitialization.kt new file mode 100644 index 00000000000..4765e8858ba --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/anonymousObjectPropertyInitialization.kt @@ -0,0 +1,14 @@ +interface T { + fun foo(): String +} + +val o = object : T { + val a = "OK" + val f = { + a + }() + + override fun foo() = f +} + +fun box() = o.foo() diff --git a/backend.native/tests/external/codegen/blackbox/objects/classCallsProtectedInheritedByCompanion.kt b/backend.native/tests/external/codegen/blackbox/objects/classCallsProtectedInheritedByCompanion.kt new file mode 100644 index 00000000000..454a3815e24 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/classCallsProtectedInheritedByCompanion.kt @@ -0,0 +1,11 @@ +open class A { + protected fun foo() = "OK" +} + +class B { + companion object : A() + + fun bar() = foo() +} + +fun box() = B().bar() diff --git a/backend.native/tests/external/codegen/blackbox/objects/flist.kt b/backend.native/tests/external/codegen/blackbox/objects/flist.kt new file mode 100644 index 00000000000..9da8a335ad7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/flist.kt @@ -0,0 +1,53 @@ +public abstract class FList() { + public abstract val head: T + public abstract val tail: FList + public abstract val empty: Boolean + + companion object { + val emptyFList = object: FList() { + public override val head: Any + get() = throw UnsupportedOperationException(); + + public override val tail: FList + get() = this + + public override val empty: Boolean + get() = true + } + } + + operator fun plus(head: T): FList = object : FList() { + override public val head: T + get() = head + + override public val empty: Boolean + get() = false + + override public val tail: FList + get() = this@FList + } +} + +public fun emptyFList(): FList = FList.emptyFList as FList + +public fun FList.reverse(where: FList = emptyFList()) : FList = + if(empty) where else tail.reverse(where + head) + +operator fun FList.iterator(): Iterator = object: Iterator { + private var cur: FList = this@iterator + + override public fun next(): T { + val res = cur.head + cur = cur.tail + return res + } + override public fun hasNext(): Boolean = !cur.empty +} + +fun box() : String { + var r = "" + for(s in (emptyFList() + "O" + "K").reverse()) { + r += s + } + return r +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/initializationOrder.kt b/backend.native/tests/external/codegen/blackbox/objects/initializationOrder.kt new file mode 100644 index 00000000000..2281132636b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/initializationOrder.kt @@ -0,0 +1,16 @@ +var result = "OK" + +class A { + companion object { + var z = result + + fun patchResult() { + result = "fail" + } + } +} + +fun box(): String { + A.patchResult() + return A.z +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt1047.kt b/backend.native/tests/external/codegen/blackbox/objects/kt1047.kt new file mode 100644 index 00000000000..cc10922307f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt1047.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +public open class Test() { + open public fun test() : Unit { + System.out?.println(hello) + } + companion object { + private val hello : String? = "Hello" + } +} + +fun box() : String { + Test().test() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt11117.kt b/backend.native/tests/external/codegen/blackbox/objects/kt11117.kt new file mode 100644 index 00000000000..439f80a6723 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt11117.kt @@ -0,0 +1,16 @@ +class A(val value: String) + +fun A.test(): String { + val o = object { + val z: String + init { + val x = value + "K" + z = x + } + } + return o.z +} + +fun box(): String { + return A("O").test() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt1136.kt b/backend.native/tests/external/codegen/blackbox/objects/kt1136.kt new file mode 100644 index 00000000000..9caf5855971 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt1136.kt @@ -0,0 +1,50 @@ +// TARGET_BACKEND: JVM + +public object SomeObject { + private val workerThread = object : Thread() { + override fun run() { + foo() + } + } + + init { + workerThread.start() + } + + private fun foo() : Unit { + } +} + +public class SomeClass() { + inner class Inner { + val copy = list + } + + private val list = ArrayList() + var status : Throwable? = null + private val workerThread = object : Thread() { + public override fun run() { + try { + list.add("123") + list.add("33") + Inner().copy.add("444") + } + catch(t: Throwable) { + status = t + } + } + } + + init { + workerThread.start() + workerThread.join() + } +} + +public fun box(): String { + var obj = SomeClass() + return if (obj.status == null) "OK" else { + (obj.status as java.lang.Throwable).printStackTrace() + "failed" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt1186.kt b/backend.native/tests/external/codegen/blackbox/objects/kt1186.kt new file mode 100644 index 00000000000..6100f7092fa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt1186.kt @@ -0,0 +1,28 @@ +enum class Color(val rgb : Int) { + RED(0xFF0000), + GREEN(0x00FF00), + BLUE(0x0000FF) +} + +enum class Direction { + NORTH, + SOUTH, + WEST, + EAST +} + +fun bar(c: Color) = when (c) { + Color.RED -> 1 + Color.GREEN -> 2 + Color.BLUE -> 3 +} + +fun foo(d: Direction) = when(d) { + Direction.NORTH -> 1 + Direction.SOUTH -> 2 + Direction.WEST -> 3 + Direction.EAST -> 4 +} + +fun box() : String = + if (foo(Direction.EAST) == 4 && bar(Color.GREEN) == 2) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt1600.kt b/backend.native/tests/external/codegen/blackbox/objects/kt1600.kt new file mode 100644 index 00000000000..e9f111a98b3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt1600.kt @@ -0,0 +1,8 @@ +abstract class Foo { + fun hello(id: T) = "O$id" +} + +class Bar: Foo() { +} + +fun box() = Bar().hello("K") diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt1737.kt b/backend.native/tests/external/codegen/blackbox/objects/kt1737.kt new file mode 100644 index 00000000000..583cac8e39d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt1737.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + return object { + fun foo(): String { + val f = {} + object : Runnable { + public override fun run() { + f() + } + } + return "OK" + } + }.foo() +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt2398.kt b/backend.native/tests/external/codegen/blackbox/objects/kt2398.kt new file mode 100644 index 00000000000..a8b11518d1a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt2398.kt @@ -0,0 +1,18 @@ +class C { + public object Obj { + val o = "O" + + object InnerObj { + fun k() = "K" + } + + class D { + val ko = "KO" + } + } +} + +fun box(): String { + val res = C.Obj.o + C.Obj.InnerObj.k() + C.Obj.D().ko + return if (res == "OKKO") "OK" else "Fail: $res" +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt2663.kt b/backend.native/tests/external/codegen/blackbox/objects/kt2663.kt new file mode 100644 index 00000000000..b7dad56133f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt2663.kt @@ -0,0 +1,10 @@ +fun box() : String { + var a = 1 + + object { + init { + a = 2 + } + } + return if (a == 2) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt2663_2.kt b/backend.native/tests/external/codegen/blackbox/objects/kt2663_2.kt new file mode 100644 index 00000000000..01007832059 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt2663_2.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box() : String { + var a = 1 + + (object: Runnable { + override public fun run() { + a = 2 + } + }).run() + return if (a == 2) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt2675.kt b/backend.native/tests/external/codegen/blackbox/objects/kt2675.kt new file mode 100644 index 00000000000..3cd63cc3262 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt2675.kt @@ -0,0 +1,16 @@ +class A() { + + fun ok() = Foo.Bar.bar() + Foo.Bar.barv + + private object Foo { + fun foo() = "O" + val foov = "K" + + public object Bar { + fun bar() = foo() + val barv = foov + } + } +} + +fun box() = A().ok() diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt2719.kt b/backend.native/tests/external/codegen/blackbox/objects/kt2719.kt new file mode 100644 index 00000000000..908dbb3a1be --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt2719.kt @@ -0,0 +1,9 @@ +class Clazz { + companion object { + val a = object { + fun run(x: String) = x + } + } +} + +fun box() = "OK" diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt2822.kt b/backend.native/tests/external/codegen/blackbox/objects/kt2822.kt new file mode 100644 index 00000000000..740aaf1698c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt2822.kt @@ -0,0 +1,7 @@ +open class A { + fun foo() = "OK" +} + +fun box() = object : A() { + fun bar() = super.foo() +}.bar() diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt3238.kt b/backend.native/tests/external/codegen/blackbox/objects/kt3238.kt new file mode 100644 index 00000000000..b1adf30137b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt3238.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +object Obj { + class Inner() { + fun ok() = "OK" + } +} + +fun box() : String { + val klass = Class.forName("Obj\$Inner")!! + val cons = klass.getConstructors()!![0] + val inner = cons.newInstance(*(arrayOfNulls(0) as Array)) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt3684.kt b/backend.native/tests/external/codegen/blackbox/objects/kt3684.kt new file mode 100644 index 00000000000..53e742f1764 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt3684.kt @@ -0,0 +1,16 @@ +open class X(private val n: String) { + + fun foo(): String { + return object : X("inner") { + fun print(): String { + return n; + } + }.print() + } +} + + +fun box() : String { + return X("OK").foo() +} + diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt4086.kt b/backend.native/tests/external/codegen/blackbox/objects/kt4086.kt new file mode 100644 index 00000000000..2aa1ca343d8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt4086.kt @@ -0,0 +1,12 @@ +interface N + +open class Base(n: N) + +class Derived : Base(object: N{}) { + +} + +fun box() : String { + Derived() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt535.kt b/backend.native/tests/external/codegen/blackbox/objects/kt535.kt new file mode 100644 index 00000000000..3821753c731 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt535.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class Identifier(t : T?, myHasDollar : Boolean) { + private val myT : T? + + public fun getName() : T? { return myT } + + companion object { + open public fun init(name : T?) : Identifier { + val id = Identifier(name, false) + return id + } + } + init { + myT = t + } +} + +fun box() : String { + var i3 : Identifier? = Identifier.init("name") + System.out?.println(i3?.getName()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt560.kt b/backend.native/tests/external/codegen/blackbox/objects/kt560.kt new file mode 100644 index 00000000000..a641c825feb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt560.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +package while_bug_1 + +import java.io.* + +open class AllEvenNum() { + + companion object { + open public fun main(args : Array?) : Unit { + var i : Int = 1 + while ((i <= 100)) { + { + if (((i % 2) == 0)) + { + System.out?.print((i.toString() + ",")) + } + + } + i = i + 1 + } + } + + } +} + +fun box() : String { + AllEvenNum.main(arrayOfNulls(0)) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/kt694.kt b/backend.native/tests/external/codegen/blackbox/objects/kt694.kt new file mode 100644 index 00000000000..945e1298489 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/kt694.kt @@ -0,0 +1,18 @@ +enum class Test { + A, + B, + C +} + +fun checkA(a: Test) = when(a) { + Test.B -> false + Test.A -> true + else -> false +} + +fun box() : String { + if(!checkA(Test.A)) return "fail" + if( checkA(Test.C)) return "fail" + if( checkA(Test.B)) return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/localFunctionInObjectInitializer_kt4516.kt b/backend.native/tests/external/codegen/blackbox/objects/localFunctionInObjectInitializer_kt4516.kt new file mode 100644 index 00000000000..c59e782da64 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/localFunctionInObjectInitializer_kt4516.kt @@ -0,0 +1,17 @@ + +object O { + val mmmap = HashMap(); + + init { + fun doStuff() { + mmmap.put("two", 2) + } + doStuff() + } +} + +fun box(): String { + val r = O.mmmap["two"] + if (r != 2) return "Fail: $r" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/methodOnObject.kt b/backend.native/tests/external/codegen/blackbox/objects/methodOnObject.kt new file mode 100644 index 00000000000..bdff2a1fec1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/methodOnObject.kt @@ -0,0 +1,5 @@ +object A { + fun result() = "OK" +} + +fun box(): String = A.result() diff --git a/backend.native/tests/external/codegen/blackbox/objects/nestedDerivedClassCallsProtectedFromCompanion.kt b/backend.native/tests/external/codegen/blackbox/objects/nestedDerivedClassCallsProtectedFromCompanion.kt new file mode 100644 index 00000000000..a9a05baa90e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/nestedDerivedClassCallsProtectedFromCompanion.kt @@ -0,0 +1,10 @@ +open class A { + companion object { + protected fun foo() = "OK" + } + class B : A() { + fun bar() = foo() + } +} + +fun box() = A.B().bar() diff --git a/backend.native/tests/external/codegen/blackbox/objects/nestedObjectWithSuperclass.kt b/backend.native/tests/external/codegen/blackbox/objects/nestedObjectWithSuperclass.kt new file mode 100644 index 00000000000..596801c7050 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/nestedObjectWithSuperclass.kt @@ -0,0 +1,18 @@ +open class A (val s: Int) { + open fun foo(): Int { + return s + } +} + +object Outer: A(1) { + object O: A(2) { + override fun foo(): Int { + val s = super.foo() + return s + 3 + } + } +} + +fun box() : String { + return if (Outer.O.foo() == 5) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/objects/objectExtendsInnerAndReferencesOuterMember.kt b/backend.native/tests/external/codegen/blackbox/objects/objectExtendsInnerAndReferencesOuterMember.kt new file mode 100644 index 00000000000..def3f9f7616 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/objectExtendsInnerAndReferencesOuterMember.kt @@ -0,0 +1,12 @@ +class A { + val x: Any get() { + return object : Inner() { + override fun toString() = foo() + } + } + + open inner class Inner + fun foo() = "OK" +} + +fun box(): String = A().x.toString() diff --git a/backend.native/tests/external/codegen/blackbox/objects/objectInLocalAnonymousObject.kt b/backend.native/tests/external/codegen/blackbox/objects/objectInLocalAnonymousObject.kt new file mode 100644 index 00000000000..f21c93edf75 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/objectInLocalAnonymousObject.kt @@ -0,0 +1,10 @@ +fun box(): String { + var boo = "OK" + var foo = object { + val bar = object { + val baz = boo + } + } + + return foo.bar.baz +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/objects/objectInitialization_kt5523.kt b/backend.native/tests/external/codegen/blackbox/objects/objectInitialization_kt5523.kt new file mode 100644 index 00000000000..3238fe1f9ce --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/objectInitialization_kt5523.kt @@ -0,0 +1,6 @@ +object A { + val a = "OK" + val b = A.a +} + +fun box() = A.b diff --git a/backend.native/tests/external/codegen/blackbox/objects/objectLiteral.kt b/backend.native/tests/external/codegen/blackbox/objects/objectLiteral.kt new file mode 100644 index 00000000000..e6030a1ccd9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/objectLiteral.kt @@ -0,0 +1,18 @@ +class C(x: Int, val y: Int) { + fun initChild(x0: Int): Any { + var x = x0 + return object { + override fun toString(): String { + x = x + y + return "child" + x + } + } + } + + val child = initChild(x) +} + +fun box(): String { + val c = C(10, 3) + return if (c.child.toString() == "child13" && c.child.toString() == "child16" && c.child.toString() == "child19") "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/objectLiteralInClosure.kt b/backend.native/tests/external/codegen/blackbox/objects/objectLiteralInClosure.kt new file mode 100644 index 00000000000..49e19260616 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/objectLiteralInClosure.kt @@ -0,0 +1,17 @@ +package p + +private class C(val y: Int) { + val initChild = { -> + object { + override fun toString(): String { + return "child" + y + } + } + } +} + +fun box(): String { + val c = C(3).initChild + val x = c().toString() + return if (x == "child3") "OK" else x +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/objectVsClassInitialization_kt5291.kt b/backend.native/tests/external/codegen/blackbox/objects/objectVsClassInitialization_kt5291.kt new file mode 100644 index 00000000000..88ec3c5bb6e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/objectVsClassInitialization_kt5291.kt @@ -0,0 +1,24 @@ +public inline fun T.with(f: T.() -> Unit): T { + this.f() + return this +} + +public class Cls { + val string = "Cls" + val buffer = StringBuilder().with { + append(string) + } +} + +public object Obj { + val string = "Obj" + val buffer = StringBuilder().with { + append(string) + } +} + +fun box(): String { + if (Cls().buffer.toString() != "Cls") return "Fail class" + if (Obj.buffer.toString() != "Obj") return "Fail object" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/objectWithSuperclass.kt b/backend.native/tests/external/codegen/blackbox/objects/objectWithSuperclass.kt new file mode 100644 index 00000000000..31c004a45fb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/objectWithSuperclass.kt @@ -0,0 +1,16 @@ +open class A { + open fun foo(): Int { + return 2 + } +} + +object O: A() { + override fun foo(): Int { + val s = super.foo() + return s + 3 + } +} + +fun box() : String { + return if (O.foo() == 5) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/objectWithSuperclassAndTrait.kt b/backend.native/tests/external/codegen/blackbox/objects/objectWithSuperclassAndTrait.kt new file mode 100644 index 00000000000..c239a3eff27 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/objectWithSuperclassAndTrait.kt @@ -0,0 +1,21 @@ +open class A { + open fun foo(): Int { + return 2 + } +} + +interface T { + open fun foo(): Int { + return 3 + } +} + +object O: A(), T { + override fun foo(): Int { + return super.foo() + super.foo() + } +} + +fun box() : String { + return if (O.foo() == 5) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/privateExtensionFromInitializer_kt4543.kt b/backend.native/tests/external/codegen/blackbox/objects/privateExtensionFromInitializer_kt4543.kt new file mode 100644 index 00000000000..ffcb2ada647 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/privateExtensionFromInitializer_kt4543.kt @@ -0,0 +1,16 @@ +class A(val result: String) + +fun a(body: A.() -> String): String { + val r = A("OK") + return r.body() +} + +object C { + private fun A.f() = result + + val g = a { + f() + } +} + +fun box() = C.g diff --git a/backend.native/tests/external/codegen/blackbox/objects/privateFunctionFromClosureInInitializer_kt5582.kt b/backend.native/tests/external/codegen/blackbox/objects/privateFunctionFromClosureInInitializer_kt5582.kt new file mode 100644 index 00000000000..5b71ab435fe --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/privateFunctionFromClosureInInitializer_kt5582.kt @@ -0,0 +1,20 @@ +interface T + +object Foo { + private fun foo(p: T) = p + + private val v: Int = { + val x = foo(O) + 42 + }() + + private object O : T + + val result = v +} + +fun box(): String { + val foo = Foo + if (foo.result != 42) return "Fail: ${foo.result}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/receiverInConstructor.kt b/backend.native/tests/external/codegen/blackbox/objects/receiverInConstructor.kt new file mode 100644 index 00000000000..b3b7a3dcb57 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/receiverInConstructor.kt @@ -0,0 +1,7 @@ +open class A(open val v: String) + +fun A.a(newv: String) = object: A("fail") { + override val v = this@a.v + newv +} + +fun box() = A("O").a("K").v diff --git a/backend.native/tests/external/codegen/blackbox/objects/safeAccess.kt b/backend.native/tests/external/codegen/blackbox/objects/safeAccess.kt new file mode 100644 index 00000000000..bbb2c6db410 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/safeAccess.kt @@ -0,0 +1,7 @@ +// KT-5159 + +object Test { + val a = "OK" +} + +fun box(): String = Test?.a diff --git a/backend.native/tests/external/codegen/blackbox/objects/simpleObject.kt b/backend.native/tests/external/codegen/blackbox/objects/simpleObject.kt new file mode 100644 index 00000000000..5b78c077a6e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/simpleObject.kt @@ -0,0 +1,7 @@ +object A { + val x: Int = 610 +} + +fun box() : String { + return if (A.x != 610) "fail" else "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/thisInConstructor.kt b/backend.native/tests/external/codegen/blackbox/objects/thisInConstructor.kt new file mode 100644 index 00000000000..02f4ce346c9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/thisInConstructor.kt @@ -0,0 +1,10 @@ +open class A(open val v: String) { +} + +open class B(open val v: String) { + fun a(newv: String) = object: A("fail") { + override val v = this@B.v + newv + } +} + +fun box() = B("O").a("K").v diff --git a/backend.native/tests/external/codegen/blackbox/objects/useAnonymousObjectAsIterator.kt b/backend.native/tests/external/codegen/blackbox/objects/useAnonymousObjectAsIterator.kt new file mode 100644 index 00000000000..4b492007eb1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/useAnonymousObjectAsIterator.kt @@ -0,0 +1,18 @@ +// KT-5869 + +operator fun Iterator.iterator(): Iterator = this + +fun box(): String { + val iterator = object : Iterator { + var i = 0 + override fun next() = i++ + override fun hasNext() = i < 5 + } + + var result = "" + for (i in iterator) { + result += i + } + + return if (result == "01234") "OK" else "Fail $result" +} diff --git a/backend.native/tests/external/codegen/blackbox/objects/useImportedMember.kt b/backend.native/tests/external/codegen/blackbox/objects/useImportedMember.kt new file mode 100644 index 00000000000..83b806eb024 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/useImportedMember.kt @@ -0,0 +1,50 @@ +import C.f +import C.p +import C.ext +import C.g1 +import C.g2 +import C.fromClass +import C.fromInterface +import C.genericFromSuper + +interface I { + fun T.fromInterface(): T = this + + fun genericFromSuper(g: G) = g +} + +open class BaseClass { + val T.fromClass: T + get() = this +} + +object C: BaseClass(), I { + fun f(s: Int) = 1 + fun f(s: String) = 2 + fun Boolean.f() = 3 + + var p: Int = 4 + val Int.ext: Int + get() = 6 + + fun g1(t: T): T = t + val T.g2: T + get() = this +} + +fun box(): String { + if (f(1) != 1) return "1" + if (f("s") != 2) return "2" + if (true.f() != 3) return "3" + if (p != 4) return "4" + p = 5 + if (p != 5) return "5" + if (5.ext != 6) return "6" + if (g1("7") != "7") return "7" + if ("8".g2 != "8") return "8" + if (9.fromInterface() != 9) return "9" + if ("10".fromClass != "10") return "10" + if (genericFromSuper("11") != "11") return "11" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/objects/useImportedMemberFromCompanion.kt b/backend.native/tests/external/codegen/blackbox/objects/useImportedMemberFromCompanion.kt new file mode 100644 index 00000000000..9523480b86a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/objects/useImportedMemberFromCompanion.kt @@ -0,0 +1,52 @@ +import Class.C.f +import Class.C.p +import Class.C.ext +import Class.C.g1 +import Class.C.g2 +import Class.C.fromClass +import Class.C.fromInterface +import Class.C.genericFromSuper + +interface I { + fun T.fromInterface(): T = this + + fun genericFromSuper(g: G) = g +} + +open class BaseClass { + val T.fromClass: T + get() = this +} + +class Class { + companion object C: BaseClass(), I { + fun f(s: Int) = 1 + fun f(s: String) = 2 + fun Boolean.f() = 3 + + var p: Int = 4 + val Int.ext: Int + get() = 6 + + fun g1(t: T): T = t + val T.g2: T + get() = this + } +} + +fun box(): String { + if (f(1) != 1) return "1" + if (f("s") != 2) return "2" + if (true.f() != 3) return "3" + if (p != 4) return "4" + p = 5 + if (p != 5) return "5" + if (5.ext != 6) return "6" + if (g1("7") != "7") return "7" + if ("8".g2 != "8") return "8" + if (9.fromInterface() != 9) return "9" + if ("10".fromClass != "10") return "10" + if (genericFromSuper("11") != "11") return "11" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/annotatedAssignment.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/annotatedAssignment.kt new file mode 100644 index 00000000000..ef6ec161a84 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/annotatedAssignment.kt @@ -0,0 +1,13 @@ +@Target(AnnotationTarget.EXPRESSION) +annotation class Annotation + +fun box(): String { + var v = 0 + @Annotation v += 1 + 2 + if (v != 3) return "fail1" + + @Annotation v = 4 + if (v != 4) return "fail2" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/assignmentOperations.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/assignmentOperations.kt new file mode 100644 index 00000000000..edbd763154e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/assignmentOperations.kt @@ -0,0 +1,36 @@ +class A() { + var x = 0 +} + +operator fun A.plusAssign(y: Int) { x += y } +operator fun A.minusAssign(y: Int) { x -= y } +operator fun A.timesAssign(y: Int) { x *= y } +operator fun A.divAssign(y: Int) { x /= y } +operator fun A.modAssign(y: Int) { x %= y } + +fun box(): String { + val original = A() + val a = original + + a += 1 + if (a !== original) return "Fail 1: $a !== $original" + if (a.x != 1) return "Fail 2: ${a.x} != 1" + + a -= 2 + if (a !== original) return "Fail 3: $a !== $original" + if (a.x != -1) return "Fail 4: ${a.x} != -1" + + a *= -10 + if (a !== original) return "Fail 5: $a !== $original" + if (a.x != 10) return "Fail 6: ${a.x} != 10" + + a /= 3 + if (a !== original) return "Fail 7: $a !== $original" + if (a.x != 3) return "Fail 8: ${a.x} != 3" + + a %= 2 + if (a !== original) return "Fail 9: $a !== $original" + if (a.x != 1) return "Fail 10: ${a.x} != 1" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/augmentedAssignmentWithArrayLHS.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/augmentedAssignmentWithArrayLHS.kt new file mode 100644 index 00000000000..0c80cc8edb7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/augmentedAssignmentWithArrayLHS.kt @@ -0,0 +1,33 @@ +var log = "" + +fun foo(): Int { + log += "foo;" + return 1 +} +fun bar(): Int { + log += "bar;" + return 42 +} + +data class A(val x: Int) { + operator fun plus(other: A) = A(x + other.x) +} + +fun box(): String { + val array = arrayOf(0, 1) + array[foo()] += bar() + + if (array[0] != 0) return "fail1a: ${array[0]}" + if (array[1] != 43) return "fail1b: ${array[0]}" + + log += "!;" + + val objArray = arrayOf(A(0), A(1)) + objArray[foo()] += A(bar()) + if (objArray[0] != A(0)) return "fail2a: ${array[0]}" + if (objArray[1] != A(43)) return "fail2b: ${array[0]}" + + if (log != "foo;bar;!;foo;bar;") return "fail3: $log" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/boolean.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/boolean.kt new file mode 100644 index 00000000000..3e347de0eef --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/boolean.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun checkLess(x: Boolean, y: Boolean) = when { + x >= y -> "Fail $x >= $y" + !(x < y) -> "Fail !($x < $y)" + !(x <= y) -> "Fail !($x <= $y)" + x > y -> "Fail $x > $y" + x.compareTo(y) >= 0 -> "Fail $x.compareTo($y) >= 0" + else -> "OK" +} + +fun box() = checkLess(false, true) diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/comparable.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/comparable.kt new file mode 100644 index 00000000000..957816c8974 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/comparable.kt @@ -0,0 +1,16 @@ +interface A : Comparable + +class B(val x: Int) : A { + override fun compareTo(other: A) = x.compareTo((other as B).x) +} + +fun checkLess(x: A, y: A) = when { + x >= y -> "Fail $x >= $y" + !(x < y) -> "Fail !($x < $y)" + !(x <= y) -> "Fail !($x <= $y)" + x > y -> "Fail $x > $y" + x.compareTo(y) >= 0 -> "Fail $x.compareTo($y) >= 0" + else -> "OK" +} + +fun box() = checkLess(B(0), B(1)) diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/doubleInt.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/doubleInt.kt new file mode 100644 index 00000000000..9818affbfba --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/doubleInt.kt @@ -0,0 +1,10 @@ +fun checkLess(x: Double, y: Int) = when { + x >= y -> "Fail $x >= $y" + !(x < y) -> "Fail !($x < $y)" + !(x <= y) -> "Fail !($x <= $y)" + x > y -> "Fail $x > $y" + x.compareTo(y) >= 0 -> "Fail $x.compareTo($y) >= 0" + else -> "OK" +} + +fun box() = checkLess(0.5, 1) diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/doubleLong.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/doubleLong.kt new file mode 100644 index 00000000000..294560659ec --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/doubleLong.kt @@ -0,0 +1,10 @@ +fun checkLess(x: Double, y: Long) = when { + x >= y -> "Fail $x >= $y" + !(x < y) -> "Fail !($x < $y)" + !(x <= y) -> "Fail !($x <= $y)" + x > y -> "Fail $x > $y" + x.compareTo(y) >= 0 -> "Fail $x.compareTo($y) >= 0" + else -> "OK" +} + +fun box() = checkLess(0.5, 1.toLong()) diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/extensionArray.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/extensionArray.kt new file mode 100644 index 00000000000..7ca0f34b787 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/extensionArray.kt @@ -0,0 +1,16 @@ +fun checkLess(x: Array, y: Array) = when { + x >= y -> "Fail $x >= $y" + !(x < y) -> "Fail !($x < $y)" + !(x <= y) -> "Fail !($x <= $y)" + x > y -> "Fail $x > $y" + x.compareTo(y) >= 0 -> "Fail $x.compareTo($y) >= 0" + else -> "OK" +} + +operator fun Array.compareTo(other: Array) = size - other.size + +fun box(): String { + val a = arrayOfNulls(0) as Array + val b = arrayOfNulls(1) as Array + return checkLess(a, b) +} diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/extensionObject.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/extensionObject.kt new file mode 100644 index 00000000000..1f355ed16e6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/extensionObject.kt @@ -0,0 +1,14 @@ +class A(val x: Int) + +operator fun A.compareTo(other: A) = x.compareTo(other.x) + +fun checkLess(x: A, y: A) = when { + x >= y -> "Fail $x >= $y" + !(x < y) -> "Fail !($x < $y)" + !(x <= y) -> "Fail !($x <= $y)" + x > y -> "Fail $x > $y" + x.compareTo(y) >= 0 -> "Fail $x.compareTo($y) >= 0" + else -> "OK" +} + +fun box() = checkLess(A(0), A(1)) diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/intDouble.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/intDouble.kt new file mode 100644 index 00000000000..a76709fe2db --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/intDouble.kt @@ -0,0 +1,10 @@ +fun checkLess(x: Int, y: Double) = when { + x >= y -> "Fail $x >= $y" + !(x < y) -> "Fail !($x < $y)" + !(x <= y) -> "Fail !($x <= $y)" + x > y -> "Fail $x > $y" + x.compareTo(y) >= 0 -> "Fail $x.compareTo($y) >= 0" + else -> "OK" +} + +fun box() = checkLess(0, 0.5) diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/intLong.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/intLong.kt new file mode 100644 index 00000000000..dc91a1d0d51 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/intLong.kt @@ -0,0 +1,10 @@ +fun checkLess(x: Int, y: Long) = when { + x >= y -> "Fail $x >= $y" + !(x < y) -> "Fail !($x < $y)" + !(x <= y) -> "Fail !($x <= $y)" + x > y -> "Fail $x > $y" + x.compareTo(y) >= 0 -> "Fail $x.compareTo($y) >= 0" + else -> "OK" +} + +fun box() = checkLess(0, 123456789123.toLong()) diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/longDouble.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/longDouble.kt new file mode 100644 index 00000000000..90e43d49215 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/longDouble.kt @@ -0,0 +1,10 @@ +fun checkLess(x: Long, y: Double) = when { + x >= y -> "Fail $x >= $y" + !(x < y) -> "Fail !($x < $y)" + !(x <= y) -> "Fail !($x <= $y)" + x > y -> "Fail $x > $y" + x.compareTo(y) >= 0 -> "Fail $x.compareTo($y) >= 0" + else -> "OK" +} + +fun box() = checkLess(0.toLong(), 0.5) diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/longInt.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/longInt.kt new file mode 100644 index 00000000000..623a3a46e01 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/compareTo/longInt.kt @@ -0,0 +1,10 @@ +fun checkLess(x: Long, y: Int) = when { + x >= y -> "Fail $x >= $y" + !(x < y) -> "Fail !($x < $y)" + !(x <= y) -> "Fail !($x <= $y)" + x > y -> "Fail $x > $y" + x.compareTo(y) >= 0 -> "Fail $x.compareTo($y) >= 0" + else -> "OK" +} + +fun box() = checkLess(-123456789123.toLong(), 0) diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/incDecOnObject.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/incDecOnObject.kt new file mode 100644 index 00000000000..0717061a9b4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/incDecOnObject.kt @@ -0,0 +1,41 @@ +class X(var value: Long) + +operator fun X.inc(): X { + this.value++ + return this +} + +operator fun X.dec(): X { + this.value-- + return this +} + +class Z { + + public var counter: Int = 0; + + public var prop: X = X(0) + get() { + counter++; return field + } + set(a: X) { + counter++ + field = a; + } +} + +fun box(): String { + var z = Z() + z.prop++ + + if (z.counter != 2) return "fail in postfix increment: ${z.counter} != 2" + if (z.prop.value != 1.toLong()) return "fail in postfix increment: ${z.prop.value} != 1" + + z = Z() + z.prop-- + + if (z.counter != 2) return "fail in postfix decrement: ${z.counter} != 2" + if (z.prop.value != -1.toLong()) return "fail in postfix decrement: ${z.prop.value} != -1" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/kt14201.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/kt14201.kt new file mode 100644 index 00000000000..3ee91af468f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/kt14201.kt @@ -0,0 +1,15 @@ +interface Intf { + val aValue: String +} + +class ClassB { + val x = { "OK" } + + val value: Intf = object : Intf { + override val aValue = x() + } +} + +fun box() : String { + return ClassB().value.aValue +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/kt14201_2.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/kt14201_2.kt new file mode 100644 index 00000000000..b95b82d9172 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/kt14201_2.kt @@ -0,0 +1,27 @@ +class A { + val z: String = "OK" +} + +class B { + operator fun A.invoke(): String = z +} + +class ClassB { + val x = A() + + fun B.test(): String { + val value = object { + val z = x() + } + return value.z + } + + fun call(): String { + return B().test() + } + +} + +fun box(): String { + return ClassB().call() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/kt4152.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/kt4152.kt new file mode 100644 index 00000000000..bc3ad4eada0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/kt4152.kt @@ -0,0 +1,29 @@ +public var inc: Int = 0; + +public var propInc: Int = 0 + get() {inc++; return field} + set(a: Int) { + inc++ + field = a + } + +public var dec: Int = 0; + +public var propDec: Int = 0; + get() { dec--; return field} + set(a: Int) { + dec-- + field = a + } + +fun box(): String { + propInc++ + if (inc != 2) return "fail in postfix increment: ${inc} != 2" + if (propInc != 1) return "fail in postfix increment: ${propInc} != 1" + + propDec-- + if (dec != -2) return "fail in postfix decrement: ${dec} != -2" + if (propDec != -1) return "fail in postfix decrement: ${propDec} != -1" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/kt4987.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/kt4987.kt new file mode 100644 index 00000000000..a95cdb8b491 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/kt4987.kt @@ -0,0 +1,9 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + operator fun Int?.inc() = (this ?: 0) + 1 + var counter: Int? = null + counter++ + return if (counter == 1) "OK" else "fail: $counter" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/nestedMaps.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/nestedMaps.kt new file mode 100644 index 00000000000..b459a515d6a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/nestedMaps.kt @@ -0,0 +1,13 @@ +object Map1 { + operator fun get(i: Int, j: Int) = Map2 +} + +object Map2 { + operator fun get(i: Int, j: Int) = 0 + operator fun set(i: Int, j: Int, newValue: Int) {} +} + +fun box(): String { + Map1[0, 0][0, 0]++ + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/operatorSetLambda.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/operatorSetLambda.kt new file mode 100644 index 00000000000..a791f7207c7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/operatorSetLambda.kt @@ -0,0 +1,16 @@ +// See KT-14999 + +object Obj { + var key = "" + var value = "" + + operator fun set(k: String, v: ((String) -> Unit) -> Unit) { + key += k + v { value += it } + } +} + +fun box(): String { + Obj["O"] = label@{ it("K") } + return Obj.key + Obj.value +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/overloadedSet.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/overloadedSet.kt new file mode 100644 index 00000000000..839722da16a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/overloadedSet.kt @@ -0,0 +1,11 @@ +object A { + operator fun get(i: Int) = 1 + operator fun set(i: Int, j: Int) {} + operator fun set(i: Int, x: Any) { throw Exception() } +} + +fun box(): String { + A[0]++ + A[0] += 1 + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/percentAsModOnBigIntegerWithoutRem.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/percentAsModOnBigIntegerWithoutRem.kt new file mode 100644 index 00000000000..0d1cdd857dc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/percentAsModOnBigIntegerWithoutRem.kt @@ -0,0 +1,11 @@ +// TARGET_BACKEND: JVM + +// LANGUAGE_VERSION: 1.0 +// FULL_JDK + +import java.math.BigInteger + +fun box(): String { + val m = BigInteger.valueOf(-2) % BigInteger.valueOf(3) + return if (m != BigInteger.valueOf(1)) "Fail: BigInteger(-2) mod BigInteger(3) == $m" else "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/remAssignmentOperation.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/remAssignmentOperation.kt new file mode 100644 index 00000000000..b0c2bf060c3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/remAssignmentOperation.kt @@ -0,0 +1,17 @@ +class A() { + var x = 5 +} + +operator fun A.modAssign(y: Int) { throw RuntimeException("mod has been called instead of rem") } +operator fun A.remAssign(y: Int) { x %= y + 1 } + +fun box(): String { + val original = A() + val a = original + + a %= 2 + if (a !== original) return "Fail 1: $a !== $original" + if (a.x != 2) return "Fail 2: ${a.x} != 2" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/operatorConventions/remOverModOperation.kt b/backend.native/tests/external/codegen/blackbox/operatorConventions/remOverModOperation.kt new file mode 100644 index 00000000000..f10fe021e65 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/operatorConventions/remOverModOperation.kt @@ -0,0 +1,18 @@ +class A() { + var x = 5 + + operator fun mod(y: Int) { throw RuntimeException("mod has been called instead of rem") } + operator fun rem(y: Int) { x -= y } +} + +fun box(): String { + val a = A() + + a % 5 + + if (a.x != 0) { + return "Fail: a.x(${a.x}) != 0" + } + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/package/boxPrimitiveTypeInClinit.kt b/backend.native/tests/external/codegen/blackbox/package/boxPrimitiveTypeInClinit.kt new file mode 100644 index 00000000000..8b8377d314b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/package/boxPrimitiveTypeInClinit.kt @@ -0,0 +1,27 @@ +var xi = 0 +var xin : Int? = 0 +var xinn : Int? = null + +var xl = 0.toLong() +var xln : Long? = 0.toLong() +var xlnn : Long? = null + +var xb = 0.toByte() +var xbn : Byte? = 0.toByte() +var xbnn : Byte? = null + +var xf = 0.toFloat() +var xfn : Float? = 0.toFloat() +var xfnn : Float? = null + +var xd = 0.toDouble() +var xdn : Double? = 0.toDouble() +var xdnn : Double? = null + +var xs = 0.toShort() +var xsn : Short? = 0.toShort() +var xsnn : Short? = null + +fun box() : String { + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/package/checkCast.kt b/backend.native/tests/external/codegen/blackbox/package/checkCast.kt new file mode 100644 index 00000000000..ffdfa30042b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/package/checkCast.kt @@ -0,0 +1,15 @@ +class C(val x: Int) { + override fun equals(rhs: Any?): Boolean { + if (rhs is C) { + val rhsC = rhs as C + return rhsC.x == x + } + return false + } +} + +fun box(): String { + val c1 = C(10) + val c2 = C(10) + return if (c1 == c2) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/package/incrementProperty.kt b/backend.native/tests/external/codegen/blackbox/package/incrementProperty.kt new file mode 100644 index 00000000000..07f0a112195 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/package/incrementProperty.kt @@ -0,0 +1,14 @@ +class Slot() { + var vitality: Int = 10000 + + fun increaseVitality(delta: Int) { + vitality += delta + if (vitality > 65535) vitality = 65535; + } +} + +fun box(): String { + val s = Slot() + s.increaseVitality(1000) + return if (s.vitality == 11000) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/package/initializationOrder.kt b/backend.native/tests/external/codegen/blackbox/package/initializationOrder.kt new file mode 100644 index 00000000000..99dc990860d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/package/initializationOrder.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String? { + val log = System.getProperty("boxtest.log") + System.clearProperty("boxtest.log") // test can be run twice + return if (log == "bca") "OK" else log +} + +val b = log("b") +val c = log("c") +val a = log("a") + +fun log(message: String) { + val value = (System.getProperty("boxtest.log") ?: "") + message + System.setProperty("boxtest.log", value) +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/package/invokespecial.kt b/backend.native/tests/external/codegen/blackbox/package/invokespecial.kt new file mode 100644 index 00000000000..fd15e17ff4d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/package/invokespecial.kt @@ -0,0 +1,48 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// KT-2202 Wrong instruction for invoke private setter + +class A { + private fun f1() { } + fun foo() { + f1() + } +} + +class B { + private val foo = 1 + get + + fun foo() { + foo + } +} + +class C { + private var foo = 1 + get + set + + fun foo() { + foo = 2 + foo + } +} + +class D { + var foo = 1 + private set + + fun foo() { + foo = 2 + } +} + +fun box(): String { + A().foo() + B().foo() + C().foo() + D().foo() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/package/mainInFiles.kt b/backend.native/tests/external/codegen/blackbox/package/mainInFiles.kt new file mode 100644 index 00000000000..b4cf8c0b19b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/package/mainInFiles.kt @@ -0,0 +1,44 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: 1.kt + +package test + +class A {} + +fun getMain(className: String): java.lang.reflect.Method { + val classLoader = A().javaClass.classLoader + return classLoader.loadClass(className).getDeclaredMethod("main", Array::class.java) +} + +fun box(): String { + val bMain = getMain("pkg.AKt") + val cMain = getMain("pkg.BKt") + + val args = Array(1, { "" }) + + bMain.invoke(null, args) + cMain.invoke(null, args) + + return args[0] +} + + + +// FILE: a.kt + +package pkg + +fun main(args: Array) { + args[0] += "O" +} + +// FILE: b.kt + +package pkg + +fun main(args: Array) { + args[0] += "K" +} diff --git a/backend.native/tests/external/codegen/blackbox/package/nullablePrimitiveNoFieldInitializer.kt b/backend.native/tests/external/codegen/blackbox/package/nullablePrimitiveNoFieldInitializer.kt new file mode 100644 index 00000000000..c0f72702d06 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/package/nullablePrimitiveNoFieldInitializer.kt @@ -0,0 +1,11 @@ +val zint : Int? = 1 +val zlong : Long? = 2 +val zbyte : Byte? = 3 +val zshort : Short? = 4 +val zchar : Char? = 'c' +val zdouble : Double? = 1.0 +val zfloat : Float? = 2.0.toFloat() + +fun box(): String { + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/package/packageLocalClassNotImportedWithDefaultImport.kt b/backend.native/tests/external/codegen/blackbox/package/packageLocalClassNotImportedWithDefaultImport.kt new file mode 100644 index 00000000000..7d185e9ee00 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/package/packageLocalClassNotImportedWithDefaultImport.kt @@ -0,0 +1,24 @@ +// FILE: box.kt + +package a + +import pack.* + +class X : SomeClass() + +fun box(): String { + X() + return "OK" +} + +// FILE: file1.kt + +package kotlin.jvm + +private class SomeClass + +// FILE: file2.kt + +package pack + +public open class SomeClass diff --git a/backend.native/tests/external/codegen/blackbox/package/packageQualifiedMethod.kt b/backend.native/tests/external/codegen/blackbox/package/packageQualifiedMethod.kt new file mode 100644 index 00000000000..92aaf32b62e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/package/packageQualifiedMethod.kt @@ -0,0 +1,6 @@ +package Foo + fun bar() = 610 + +fun box(): String { + return if (Foo.bar() == 610) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/package/privateTopLevelPropAndVarInInner.kt b/backend.native/tests/external/codegen/blackbox/package/privateTopLevelPropAndVarInInner.kt new file mode 100644 index 00000000000..b61fd243ab9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/package/privateTopLevelPropAndVarInInner.kt @@ -0,0 +1,4 @@ +private var x = "O" +private fun f() = "K" + +fun box() = { x + f() }() diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/assign.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/assign.kt new file mode 100644 index 00000000000..97730470dfc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/assign.kt @@ -0,0 +1,8 @@ +fun box(): String { + val l = ArrayList() + l.add(1) + var x = l[0] + x = 2 + if (x != 2) return "Fail: $x}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/compareTo.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/compareTo.kt new file mode 100644 index 00000000000..288a8111d76 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/compareTo.kt @@ -0,0 +1,9 @@ +fun box(): String { + val l = ArrayList() + l.add(1) + val x = l[0] < 2 + if (x != true) return "Fail: $x}" + val y = l[0].compareTo(2) + if (y != -1) return "Fail (y): $y}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/dec.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/dec.kt new file mode 100644 index 00000000000..04574676e01 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/dec.kt @@ -0,0 +1,14 @@ +fun box(): String { + val l = ArrayList() + l.add(1) + var x = l[0] + var y = l[0] + l[0]-- + --l[0] + x-- + --y + if (l[0] != -1) return "Fail: ${l[0]}" + if (x != 0) return "Fail x: $x" + if (y != 0) return "Fail y: $y" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/div.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/div.kt new file mode 100644 index 00000000000..1d19aa08bde --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/div.kt @@ -0,0 +1,7 @@ +fun box(): String { + val l = ArrayList() + l.add(2) + val x = l[0] / 2 + if (x != 1) return "Fail: $x}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/equals.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/equals.kt new file mode 100644 index 00000000000..f11e683d8cf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/equals.kt @@ -0,0 +1,7 @@ +fun box(): String { + val l = ArrayList() + l.add(1) + val x = l[0] == 2 + if (x != false) return "Fail: $x}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/hashCode.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/hashCode.kt new file mode 100644 index 00000000000..884ce0f7752 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/hashCode.kt @@ -0,0 +1,7 @@ +fun box(): String { + val l = ArrayList() + l.add(1) + val x = l[0].hashCode() + if (x != 1) return "Fail: $x}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/identityEquals.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/identityEquals.kt new file mode 100644 index 00000000000..495dace669b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/identityEquals.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + val l = java.util.ArrayList() + l.add(1000) + + val x = l[0] === 1000 + if (x) return "Fail: $x" + val x1 = l[0] === 1 + if (x1) return "Fail 1: $x" + val x2 = l[0] === l[0] + if (!x2) return "Fail 2: $x" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/inc.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/inc.kt new file mode 100644 index 00000000000..25de0090050 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/inc.kt @@ -0,0 +1,14 @@ +fun box(): String { + val l = ArrayList() + l.add(1) + var x = l[0] + var y = l[0] + l[0]++ + ++l[0] + x++ + ++y + if (l[0] != 3) return "Fail: ${l[0]}" + if (x != 2) return "Fail x: $x" + if (y != 2) return "Fail y: $y" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/minus.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/minus.kt new file mode 100644 index 00000000000..cf14e881a9a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/minus.kt @@ -0,0 +1,7 @@ +fun box(): String { + val l = ArrayList() + l.add(1) + val x = l[0] - 1 + if (x != 0) return "Fail: $x}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/mod.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/mod.kt new file mode 100644 index 00000000000..f72a03f668d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/mod.kt @@ -0,0 +1,7 @@ +fun box(): String { + val l = ArrayList() + l.add(2) + val x = l[0] % 2 + if (x != 0) return "Fail: $x}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/not.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/not.kt new file mode 100644 index 00000000000..0c280a8febc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/not.kt @@ -0,0 +1,7 @@ +fun box(): String { + val l = ArrayList() + l.add(true) + val x = !l[0] + if (x) return "Fail: $x}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/notEquals.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/notEquals.kt new file mode 100644 index 00000000000..0f57a857b28 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/notEquals.kt @@ -0,0 +1,7 @@ +fun box(): String { + val l = ArrayList() + l.add(1) + val x = l[0] != 1 + if (x != false) return "Fail: $x}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/plus.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/plus.kt new file mode 100644 index 00000000000..97b8744ab0d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/plus.kt @@ -0,0 +1,7 @@ +fun box(): String { + val l = ArrayList() + l.add(1) + val x = l[0] + 1 + if (x != 2) return "Fail: $x}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/plusAssign.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/plusAssign.kt new file mode 100644 index 00000000000..cc3512f76a0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/plusAssign.kt @@ -0,0 +1,10 @@ +fun box(): String { + val l = ArrayList() + l.add(1) + var x = l[0] + x += 1 + l[0] += 1 + if (l[0] != 2) return "Fail: ${l[0]}" + if (x != 2) return "Fail: $x}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/rangeTo.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/rangeTo.kt new file mode 100644 index 00000000000..ceb1961f5df --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/rangeTo.kt @@ -0,0 +1,10 @@ +fun box(): String { + val l = ArrayList() + l.add(2) + val sb = StringBuilder() + for (i in l[0]..3) { + sb.append(i) + } + if (sb.toString() != "23") return "Fail: $sb}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/times.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/times.kt new file mode 100644 index 00000000000..939bc056018 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/times.kt @@ -0,0 +1,7 @@ +fun box(): String { + val l = ArrayList() + l.add(1) + val x = l[0] * 2 + if (x != 2) return "Fail: $x}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/toShort.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/toShort.kt new file mode 100644 index 00000000000..429eaf77336 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/toShort.kt @@ -0,0 +1,7 @@ +fun box(): String { + val l = ArrayList() + l.add(1) + val x = l[0].toShort() + if (x != 1.toShort()) return "Fail: $x}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/toString.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/toString.kt new file mode 100644 index 00000000000..3ad15f84649 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/toString.kt @@ -0,0 +1,7 @@ +fun box(): String { + val l = ArrayList() + l.add(1) + val x = "${l[0]}" + if (x != "1") return "Fail: $x}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/unaryMinus.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/unaryMinus.kt new file mode 100644 index 00000000000..30ed37ccf3b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/unaryMinus.kt @@ -0,0 +1,7 @@ +fun box(): String { + val l = ArrayList() + l.add(1) + val x = -l[0] + if (x != -1) return "Fail: $x" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/unaryPlus.kt b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/unaryPlus.kt new file mode 100644 index 00000000000..c987878a3a1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/platformTypes/primitives/unaryPlus.kt @@ -0,0 +1,7 @@ +fun box(): String { + val l = ArrayList() + l.add(1) + val x = +l[0] + if (x != 1) return "Fail: $x}" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/comparisonWithNaN.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/comparisonWithNaN.kt new file mode 100644 index 00000000000..2f1186ca3bf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/comparisonWithNaN.kt @@ -0,0 +1,61 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// This test checks that our bytecode is consistent with javac bytecode + +fun _assert(condition: Boolean) { + if (!condition) throw AssertionError("Fail") +} + +fun _assertFalse(condition: Boolean) = _assert(!condition) + +fun box(): String { + var dnan = java.lang.Double.NaN + if (System.nanoTime() < 0) dnan = 3.14 // To avoid possible compile-time const propagation + + _assertFalse(0.0 < dnan) + _assertFalse(0.0 > dnan) + _assertFalse(0.0 <= dnan) + _assertFalse(0.0 >= dnan) + _assertFalse(0.0 == dnan) + _assertFalse(dnan < 0.0) + _assertFalse(dnan > 0.0) + _assertFalse(dnan <= 0.0) + _assertFalse(dnan >= 0.0) + _assertFalse(dnan == 0.0) + _assertFalse(dnan < dnan) + _assertFalse(dnan > dnan) + _assertFalse(dnan <= dnan) + _assertFalse(dnan >= dnan) + _assertFalse(dnan == dnan) + + // Double.compareTo: "NaN is considered by this method to be equal to itself and greater than all other values" + _assert(0.0.compareTo(dnan) == -1) + _assert(dnan.compareTo(0.0) == 1) + _assert(dnan.compareTo(dnan) == 0) + + var fnan = java.lang.Float.NaN + if (System.nanoTime() < 0) fnan = 3.14f + + _assertFalse(0.0f < fnan) + _assertFalse(0.0f > fnan) + _assertFalse(0.0f <= fnan) + _assertFalse(0.0f >= fnan) + _assertFalse(0.0f == fnan) + _assertFalse(fnan < 0.0f) + _assertFalse(fnan > 0.0f) + _assertFalse(fnan <= 0.0f) + _assertFalse(fnan >= 0.0f) + _assertFalse(fnan == 0.0f) + _assertFalse(fnan < fnan) + _assertFalse(fnan > fnan) + _assertFalse(fnan <= fnan) + _assertFalse(fnan >= fnan) + _assertFalse(fnan == fnan) + + _assert(0.0.compareTo(fnan) == -1) + _assert(fnan.compareTo(0.0) == 1) + _assert(fnan.compareTo(fnan) == 0) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/comparisonWithNullCallsFun.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/comparisonWithNullCallsFun.kt new file mode 100644 index 00000000000..0948f0eb0b9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/comparisonWithNullCallsFun.kt @@ -0,0 +1,13 @@ +var entered = 0 + +fun foo(t: T): T { + entered++ + return t +} + +fun box(): String { + if (foo(null) == null) {} + if (null == foo(null)) {} + if (foo(null) == foo(null)) {} + return if (entered == 4) "OK" else "Fail $entered" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/ea35963.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/ea35963.kt new file mode 100644 index 00000000000..6d58f3f2de4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/ea35963.kt @@ -0,0 +1,6 @@ +fun box(): String { + if (1 != 0) { + 1 + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/equalsHashCodeToString.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/equalsHashCodeToString.kt new file mode 100644 index 00000000000..7d4684e70bd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/equalsHashCodeToString.kt @@ -0,0 +1,60 @@ +fun box(): String { + val b: Byte = 42 + val c: Char = 'z' + val s: Short = 239 + val i: Int = -1 + val j: Long = -42L + val f: Float = 3.14f + val d: Double = -2.72 + val z: Boolean = true + + b.equals(b) + b == b + b.hashCode() + b.toString() + "$b" + + c.equals(c) + c == c + c.hashCode() + c.toString() + "$c" + + s.equals(s) + s == s + s.hashCode() + s.toString() + "$s" + + i.equals(i) + i == i + i.hashCode() + i.toString() + "$i" + + j.equals(j) + j == j + j.hashCode() + j.toString() + "$j" + + f.equals(f) + f == f + f.hashCode() + f.toString() + "$f" + + d.equals(d) + d == d + d.hashCode() + d.toString() + "$d" + + z.equals(z) + z == z + z.hashCode() + z.toString() + "$z" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/incrementByteCharShort.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/incrementByteCharShort.kt new file mode 100644 index 00000000000..59b3f12b2ef --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/incrementByteCharShort.kt @@ -0,0 +1,22 @@ +fun byteArg(b: Byte) {} +fun charArg(c: Char) {} +fun shortArg(s: Short) {} + +fun box(): String { + var b = 42.toByte() + b++ + ++b + byteArg(b) + + var c = 'x' + c++ + ++c + charArg(c) + + var s = 239.toShort() + s++ + ++s + shortArg(s) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/intLiteralIsNotNull.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/intLiteralIsNotNull.kt new file mode 100644 index 00000000000..d9f9d0420f1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/intLiteralIsNotNull.kt @@ -0,0 +1 @@ +fun box() = if (10!! == 10) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt1054.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt1054.kt new file mode 100644 index 00000000000..6393e3a0ec0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt1054.kt @@ -0,0 +1,17 @@ +fun box() : String { + return if(true.and(true)) "OK" else "fail" +} + +fun Boolean.and(other : Boolean) : Boolean{ + if(other == true) { + if(this == true){ + return true ; + } + else{ + return false; + } + } + else { + return false; + } +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt1055.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt1055.kt new file mode 100644 index 00000000000..1a03f1e3b6b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt1055.kt @@ -0,0 +1,6 @@ +fun box() : String { + val a = "lala" + if(a !== a) return "fail 1" + if(a === a) return "OK" + return "fail 2" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt1093.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt1093.kt new file mode 100644 index 00000000000..f1b56508700 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt1093.kt @@ -0,0 +1,8 @@ +val f : (Any) -> String = { it.toString() } + +fun box() : String { + if(!(f === f)) return "fail 1" + if(!(f == f)) return "fail 2" + if(!(f.equals(f))) return "fail 3" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt13023.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt13023.kt new file mode 100644 index 00000000000..602654d9563 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt13023.kt @@ -0,0 +1,20 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + val b = 'b' + val c = 'c' + assertEquals('c', b + 1) + assertEquals('a', b - 1) + assertEquals(1, c - b) + + val list = listOf('b', 'a') + assertEquals('c', list[0] + 1) + assertEquals('a', list[0] - 1) + assertEquals(1, list[0] - list[1]) + assertEquals(1, list[0] - 'a') + assertEquals(1, 'b' - list[1]) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt14868.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt14868.kt new file mode 100644 index 00000000000..1416af7135b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt14868.kt @@ -0,0 +1,6 @@ + +fun box(): String { + val x: Number = 75 + + return "O" + x.toChar() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt1508.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt1508.kt new file mode 100644 index 00000000000..28e534afe39 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt1508.kt @@ -0,0 +1,6 @@ +fun test( n : Number ) = n.toInt().toLong() + n.toLong() + +fun box() : String { + val n : Number = 10 + return if(test(n) == 20.toLong()) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt1634.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt1634.kt new file mode 100644 index 00000000000..8cdc1a36907 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt1634.kt @@ -0,0 +1,4 @@ +fun box(): String { + !true + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt2251.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt2251.kt new file mode 100644 index 00000000000..d75041090e5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt2251.kt @@ -0,0 +1,39 @@ +class A(var b: Byte) { + fun c(d: Short) = (b + d.toByte()).toChar() +} + +fun box() : String { + if(A(10.toByte()).c(20.toShort()) != 30.toByte().toChar()) return "plus failed" + + var x = 20.toByte() + var y = 20.toByte() + val foo = { + x++ + ++x + } + + if(++x != 21.toByte() || x++ != 21.toByte() || foo() != 24.toByte() || x != 24.toByte()) return "shared byte fail" + if(++y != 21.toByte() || y++ != 21.toByte() || y != 22.toByte()) return "byte fail" + + var xs = 20.toShort() + var ys = 20.toShort() + val foos = { + xs++ + ++xs + } + + if(++xs != 21.toShort() || xs++ != 21.toShort() || foos() != 24.toShort() || xs != 24.toShort()) return "shared short fail" + if(++ys != 21.toShort() || ys++ != 21.toShort() || ys != 22.toShort()) return "short fail" + + var xc = 20.toChar() + var yc = 20.toChar() + val fooc = { + xc++ + ++xc + } + + if(++xc != 21.toChar() || xc++ != 21.toChar() || fooc() != 24.toChar() || xc != 24.toChar()) return "shared char fail" + if(++yc != 21.toChar() || yc++ != 21.toChar() || yc != 22.toChar()) return "char fail" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt2269.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt2269.kt new file mode 100644 index 00000000000..e1896168c8f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt2269.kt @@ -0,0 +1,13 @@ +fun box() : String { + 230?.toByte()?.hashCode() + 9.hashCode() + + if(230.equals(9.toByte())) { + return "fail" + } + + if(230 == 9.toByte().toInt()) { + return "fail" + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt2275.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt2275.kt new file mode 100644 index 00000000000..4dc1296a0e5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt2275.kt @@ -0,0 +1,5 @@ +fun box(): String { + (0.toLong() as Number?)?.toByte() + (0 as Int?)?.toDouble() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt239.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt239.kt new file mode 100644 index 00000000000..f36b32743d8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt239.kt @@ -0,0 +1,5 @@ +fun box() : String { + val i : Int? = 0 + val j = i?.plus(3) //verify error + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt242.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt242.kt new file mode 100644 index 00000000000..c1a99510817 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt242.kt @@ -0,0 +1,19 @@ +fun box() : String { + val i: Int? = 7 + val j: Int? = null + val k = 7 + + //verify errors + if (i == 7) {} + if (7 == i) {} + + if (j == 7) {} + if (7 == j) {} + + if (i == k) {} + if (k == i) {} + + if (j == k) {} + if (k == j) {} + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt243.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt243.kt new file mode 100644 index 00000000000..41c93f54971 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt243.kt @@ -0,0 +1,11 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box() : String { + val t = java.lang.String.copyValueOf(java.lang.String("s").toCharArray()) + val i = java.lang.Integer.MAX_VALUE + val j = java.lang.Integer.valueOf(15) + val s = java.lang.String.valueOf(1) + val l = java.util.Collections.emptyList() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt248.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt248.kt new file mode 100644 index 00000000000..0607b21341f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt248.kt @@ -0,0 +1,7 @@ +fun box() : String { + val b = true as? Boolean //exception + val i = 1 as Int //exception + val j = 1 as Int? //ok + val s = "s" as String //ok + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt2768.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt2768.kt new file mode 100644 index 00000000000..b2b0ec976ef --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt2768.kt @@ -0,0 +1,17 @@ +fun assertEquals(a: T, b: T) { + if (a != b) throw AssertionError("$a != $b") +} + +fun box(): String { + val bytePos = 128.toByte() // Byte.MAX_VALUE + 1 + assertEquals(-128, bytePos.toInt()) // correct, wrapped to Byte.MIN_VALUE + + val shortPos = 32768.toShort() // Short.MAX_VALUE + 1 + assertEquals(-32768, shortPos.toInt()) // correct, wrapped to Short.MIN_VALUE + + assertEquals((-128).toByte().toString(), "-128") + // TODO: KT-2780 + // assertEquals((-128.toByte()).toString(), "-128") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt2794.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt2794.kt new file mode 100644 index 00000000000..bd6c80dced5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt2794.kt @@ -0,0 +1,6 @@ +fun box () : String { + val b = 4.toByte() + val s = 5.toShort() + val c: Char = 'A' + return if( "$b" == "4" && " $b" == " 4" && "$s" == "5" && " $s" == " 5" && "$c" == "A" && " $c" == " A") "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt3078.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt3078.kt new file mode 100644 index 00000000000..cd834c89b2f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt3078.kt @@ -0,0 +1,7 @@ +fun box(): String { + if (1 >= 1.9) return "Fail #1" + if (1.compareTo(1.1) >= 0) return "Fail #2" + if (1.9 <= 1) return "Fail #3" + if (1.1.compareTo(1) <= 0) return "Fail #4" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt3517.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt3517.kt new file mode 100644 index 00000000000..535f32308cd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt3517.kt @@ -0,0 +1,6 @@ +// KT-3517 Can't call .equals() on a boolean + +fun box(): String { + val a = false + return if (true.equals(true) && a.equals(false)) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt3576.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt3576.kt new file mode 100644 index 00000000000..955272f0faa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt3576.kt @@ -0,0 +1,9 @@ +object TestObject { + val testFloat: Float = 0.9999.toFloat() + val otherFloat: Float = 1.01.toFloat() +} + +fun box(): String { + return if (TestObject.testFloat.equals(0.9999.toFloat()) + && TestObject.otherFloat.equals(1.01.toFloat())) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt3613.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt3613.kt new file mode 100644 index 00000000000..c578f93fb7e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt3613.kt @@ -0,0 +1,6 @@ +fun foo(): Int? = 42 + +fun box(): String { + if (foo()!! > 239) return "Fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt4097.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt4097.kt new file mode 100644 index 00000000000..04cc01c3f3a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt4097.kt @@ -0,0 +1,15 @@ +fun box(): String { + val shouldBeTrue = 555555555555555555L in 123456789123456789L..987654321987654321L + if (!shouldBeTrue) return "Fail 1" + + val shouldBeFalse = 5000000000L in 6000000000L..9000000000L + if (shouldBeFalse) return "Fail 2" + + if (123123123123L !in 100100100100L..200200200200L) return "Fail 3" + + return when (9876543210) { + in 2000000000L..3333333333L -> "Fail 4" + !in 8888888888L..9999999999L -> "Fail 5" + else -> "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt4098.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt4098.kt new file mode 100644 index 00000000000..a74f18feeac --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt4098.kt @@ -0,0 +1,10 @@ +fun box(): String { + val c: Char? = '0' + c!!.toInt() + + "123456"?.get(0)!!.toInt() + + "123456"!!.get(0).toInt() + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt4210.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt4210.kt new file mode 100644 index 00000000000..4f3b16d0e6e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt4210.kt @@ -0,0 +1,16 @@ +fun box(): String { + val s: String? = "abc" + val c = s?.get(0)!! - 'b' + if (c != -1) return "Fail c: $c" + + val d = 'b' - s?.get(2)!! + if (d != -1) return "Fail d: $d" + + val e = s?.get(2)!! - s?.get(0)!! + if (e != 2) return "Fail e: $e" + + val f = s?.get(2)!!.minus(s?.get(0)!!) + if (f != 2) return "Fail f: $f" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt4251.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt4251.kt new file mode 100644 index 00000000000..eda602589c0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt4251.kt @@ -0,0 +1,5 @@ +fun box(): String { + val a: Char? = 'a' + val result = a!! < 'b' + return if (result) "OK" else "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt446.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt446.kt new file mode 100644 index 00000000000..c148b490f81 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt446.kt @@ -0,0 +1,5 @@ +fun box(): String { + var s = "s" + s += 1 + return if (s == "s1") "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt518.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt518.kt new file mode 100644 index 00000000000..f1ec08f1c2f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt518.kt @@ -0,0 +1,15 @@ + +fun foo(i : Int?, a : Any?) { + i?.plus(1) + if (i != null) { + i + 1 + if (a is String) { + a[0] + } + } +} + +fun box () : String { + foo(2, "239") + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt6590_identityEquals.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt6590_identityEquals.kt new file mode 100644 index 00000000000..f21a8f1f6a7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt6590_identityEquals.kt @@ -0,0 +1,15 @@ +fun box(): String { + val i: Int = 10000 + if (!(i === i)) return "Fail int ===" + if (i !== i) return "Fail int !==" + + val j: Long = 123L + if (!(j === j)) return "Fail long ===" + if (j !== j) return "Fail long !==" + + val d: Double = 3.14 + if (!(d === d)) return "Fail double ===" + if (d !== d) return "Fail double !==" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt665.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt665.kt new file mode 100644 index 00000000000..b8bd69b6550 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt665.kt @@ -0,0 +1,12 @@ +fun f(x: Long, zzz: Long = 1): Long +{ + return if (x <= 1) zzz + else f(x-1, x*zzz) +} + +fun box() : String +{ + val six: Long = 6; + if (f(six) != 720.toLong()) return "Fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt684.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt684.kt new file mode 100644 index 00000000000..5441850af87 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt684.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun escapeChar(c : Char) : String? = when (c) { + '\\' -> "\\\\" + '\n' -> "\\n" + '"' -> "\\\"" + else -> "" + c +} + +fun String.escape(i : Int = 0, result : String = "") : String = + if (i == length) result + else escape(i + 1, result + escapeChar(get(i))) + +fun box() : String { + val s = " System.out?.println(\"fun escapeChar(c : Char) : String? = when (c) {\");\n System.out?.println(\" '\\\\\\\\' => \\\"\\\\\\\\\\\\\\\\\\\"\");\n System.out?.println(\" '\\\\n' => \\\"\\\\\\\\n\\\"\");\n System.out?.println(\" '\\\"' => \\\"\\\\\\\\\\\\\\\"\\\"\");\n System.out?.println(\" else => String.valueOf(c)\");\n System.out?.println(\"}\");\n System.out?.println();\n System.out?.println(\"fun String.escape(i : Int = 0, result : String = \\\"\\\") : String =\");\n System.out?.println(\" if (i == length) result\");\n System.out?.println(\" else escape(i + 1, result + escapeChar(this.get(i)))\");\n System.out?.println();\n System.out?.println(\"fun main(args : Array) {\");\n System.out?.println(\" val s = \\\"\" + s.escape() + \"\\\";\");\n System.out?.println(s);\n}\n"; + System.out?.println("fun escapeChar(c : Char) : String? = when (c) {"); + System.out?.println(" '\\\\' => \"\\\\\\\\\""); + System.out?.println(" '\\n' => \"\\\\n\""); + System.out?.println(" '\"' => \"\\\\\\\"\""); + System.out?.println(" else => String.valueOf(c)"); + System.out?.println("}"); + System.out?.println(); + System.out?.println("fun String.escape(i : Int = 0, result : String = \"\") : String ="); + System.out?.println(" if (i == length) result"); + System.out?.println(" else escape(i + 1, result + escapeChar(this.get(i)))"); + System.out?.println(); + System.out?.println("fun main(args : Array) {"); + System.out?.println(" val s = \"" + s.escape() + "\";"); + System.out?.println(s); + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt711.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt711.kt new file mode 100644 index 00000000000..ffe360595a5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt711.kt @@ -0,0 +1 @@ +fun box() = if ((1 ?: 0) == 1) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt737.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt737.kt new file mode 100644 index 00000000000..bdf9a4f5af7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt737.kt @@ -0,0 +1,5 @@ +fun box(): String { + if (3.compareTo(2) != 1) return "Fail #1" + if (5.toByte().compareTo(10.toLong()) >= 0) return "Fail #2" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt752.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt752.kt new file mode 100644 index 00000000000..a62581eefb7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt752.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +package demo_range + +operator fun Int?.rangeTo(other : Int?) : IntRange = this!!.rangeTo(other!!) + +fun box() : String { + val x : Int? = 10 + val y : Int? = 12 + + for (i in x..y) + System.out?.println(i.inv()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt753.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt753.kt new file mode 100644 index 00000000000..f66201f9927 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt753.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +package bitwise_demo + +fun Long?.shl(bits : Int?) : Long = this!!.shl(bits!!) + +fun box() : String { + val x : Long? = 10 + val y : Int? = 12 + + System.out?.println(x.shl(y)) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt756.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt756.kt new file mode 100644 index 00000000000..6d65494990b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt756.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +package demo_range + +operator fun Int?.unaryPlus() : Int = this!!.unaryPlus() +operator fun Int?.dec() : Int = this!!.dec() +operator fun Int?.inc() : Int = this!!.inc() +operator fun Int?.unaryMinus() : Int = this!!.unaryMinus() + +fun box() : String { + val x : Int? = 10 + System.out?.println(x?.inv())// * x?.unaryPlus() * x?.dec() * x?.unaryMinus() as Number) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt757.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt757.kt new file mode 100644 index 00000000000..39bc99d7d8f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt757.kt @@ -0,0 +1,12 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +package demo_long + +fun Long?.inv() : Long = this!!.inv() + +fun box() : String { + val x : Long? = 10 + System.out?.println(x.inv()) + return if(x.inv() == -11.toLong()) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt828.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt828.kt new file mode 100644 index 00000000000..06e63bec23c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt828.kt @@ -0,0 +1,15 @@ +package demo + +fun box() : String { + var res : Boolean = true + res = (res and false) + res = (res or false) + res = (res xor false) + res = (true and false) + res = (true or false) + res = (true xor false) + res = (!true) + res = (true && false) + res = (true || false) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt877.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt877.kt new file mode 100644 index 00000000000..094c5f88fae --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt877.kt @@ -0,0 +1,9 @@ +fun box() : String { + var a : Int = -1 + if((+a) != -1) return "fail 1" + a = 1 + if((+a) != 1) return "fail 2" + if((+-1) != -1) return "fail 3" + if((-+a) != -1) return "fail 4" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt882.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt882.kt new file mode 100644 index 00000000000..15da30a150e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt882.kt @@ -0,0 +1,7 @@ +val _0 : Double = 0.0 +val _0dbl : Double = 0.toDouble() + +fun box() : String { + if(_0 != _0dbl) return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt887.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt887.kt new file mode 100644 index 00000000000..c03be7c8835 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt887.kt @@ -0,0 +1,5 @@ +class Book(val name: String) : Comparable { + override fun compareTo(other: Book) = name.compareTo(other.name) +} + +fun box() = if(Book("239").compareTo(Book("932")) != 0) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt935.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt935.kt new file mode 100644 index 00000000000..92674333923 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/kt935.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +package bottles + +fun box() : String { + var bottles = 10 + while (bottles > 0) { + print(bottlesOfBeer(bottles) + " on the wall, ") + println(bottlesOfBeer(bottles) + ".") + print("Take one down, pass it around, ") + if (--bottles == 0) { + println("no more bottles of beer on the wall.") + } + else { + println(bottlesOfBeer(bottles) + " on the wall.") + } + } + return "OK" +} + +fun bottlesOfBeer(count : Int) : String { + val result = StringBuilder() + result += count + result += if (count > 1) " bottles of beer" else " bottle of beer" + return result.toString() ?: "" +} + +// An excerpt from the standard library +fun print(message : String) { System.out?.print(message) } +fun println(message : String) { System.out?.println(message) } +operator fun StringBuilder.plusAssign(o : Any) { append(o) } +val Array.isEmpty : Boolean get() = size == 0 diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/nullAsNullableIntIsNull.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/nullAsNullableIntIsNull.kt new file mode 100644 index 00000000000..a9273088e10 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/nullAsNullableIntIsNull.kt @@ -0,0 +1,9 @@ +fun box(): String { + try { + if ((null as Int?)!! == 10) return "Fail #1" + return "Fail #2" + } + catch (e: Exception) { + return "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/nullableCharBoolean.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/nullableCharBoolean.kt new file mode 100644 index 00000000000..ddc86b85777 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/nullableCharBoolean.kt @@ -0,0 +1,9 @@ +fun box(): String { + val c: Char? = 'a' + if (c!! - 'a' != 0) return "Fail c" + + val b: Boolean? = false + if (b!!) return "Fail b" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/number.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/number.kt new file mode 100644 index 00000000000..faefeadd942 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/number.kt @@ -0,0 +1,36 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: FortyTwoExtractor.java + +public class FortyTwoExtractor { + private Number fortyTwo = new FortyTwo(); + + public int intValue() { + return fortyTwo.intValue(); + } +} + +// FILE: FortyTwoExtractor.kt + +class FortyTwo : Number() { + override fun toByte() = 42.toByte() + + override fun toShort() = 42.toShort() + + override fun toInt() = 42 + + override fun toLong() = 42L + + override fun toFloat() = 42.0f + + override fun toDouble() = 42.0 + + override fun toChar() = 42.toChar() +} + +fun box(): String { + val extractor = FortyTwoExtractor() + if (extractor.intValue() != 42) return "FAIL" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/rangeTo.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/rangeTo.kt new file mode 100644 index 00000000000..7d55b63daf9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/rangeTo.kt @@ -0,0 +1,62 @@ +fun box(): String { + val b: Byte = 42 + val c: Char = 'z' + val s: Short = 239 + val i: Int = -1 + val j: Long = -42L + + b.rangeTo(b) + b..b + b.rangeTo(s) + b..s + b.rangeTo(i) + b..i + b.rangeTo(j) + b..j + + c.rangeTo(c) + c..c + + s.rangeTo(b) + s..b + s.rangeTo(s) + s..s + s.rangeTo(i) + s..i + s.rangeTo(j) + s..j + + i.rangeTo(b) + i..b + i.rangeTo(s) + i..s + i.rangeTo(i) + i..i + i.rangeTo(j) + i..j + + j.rangeTo(b) + j..b + j.rangeTo(s) + j..s + j.rangeTo(i) + j..i + j.rangeTo(j) + j..j + + return "OK" +} + +/* +fun main(args: Array) { + val s = "bcsij" + for (i in s) { + for (j in s) { + if ((i == 'c') != (j == 'c')) continue + println(" $i.rangeTo($j)") + println(" $i..$j") + } + println() + } +} +*/ diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/substituteIntForGeneric.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/substituteIntForGeneric.kt new file mode 100644 index 00000000000..6b32d00e18e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/substituteIntForGeneric.kt @@ -0,0 +1,11 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class L(var a: T) {} + +fun foo() = L(5).a + +fun box(): String { + val x: Any = foo() + return if (x is Integer) "OK" else "Fail $x" +} diff --git a/backend.native/tests/external/codegen/blackbox/primitiveTypes/unboxComparable.kt b/backend.native/tests/external/codegen/blackbox/primitiveTypes/unboxComparable.kt new file mode 100644 index 00000000000..870989087fd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/primitiveTypes/unboxComparable.kt @@ -0,0 +1,5 @@ +fun foo(x: Int) = x + +fun bar(x: Comparable) = if (x is Int) foo(x) else 0 + +fun box() = if (bar(42) == 42) "OK" else "Fail" diff --git a/backend.native/tests/external/codegen/blackbox/private/arrayConvention.kt b/backend.native/tests/external/codegen/blackbox/private/arrayConvention.kt new file mode 100644 index 00000000000..5d778552e83 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/private/arrayConvention.kt @@ -0,0 +1,21 @@ +var result = "fail" + +private operator fun X.get(name: String) = name + "K" +private operator fun X.set(name: String, v: String) { + result = v +} + +class X { + fun test() : String { + if (this["O"] != "OK") return "fail 1: ${this["O"]}" + + this["O"] += "K" + if (result != "OKK") return "fail 2: ${result}" + + return "OK" + } +} + +fun box(): String { + return X().test() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/private/kt9855.kt b/backend.native/tests/external/codegen/blackbox/private/kt9855.kt new file mode 100644 index 00000000000..03e1658e1a5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/private/kt9855.kt @@ -0,0 +1,15 @@ +class MyString(var content : String) + +object Greeter { + fun sayHello(name : String): String { + var result = MyString(name) + result += "K" + return result.content + } +} + +private operator fun MyString.plus(suffix: String) : MyString = MyString("${this.content}$suffix") + +fun box(): String { + return Greeter.sayHello("O") +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/privateConstructors/base.kt b/backend.native/tests/external/codegen/blackbox/privateConstructors/base.kt new file mode 100644 index 00000000000..f856a95217b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/privateConstructors/base.kt @@ -0,0 +1,9 @@ +// See also KT-6299 +public open class Outer private constructor() { + class Inner: Outer() +} + +fun box(): String { + val outer = Outer.Inner() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/privateConstructors/captured.kt b/backend.native/tests/external/codegen/blackbox/privateConstructors/captured.kt new file mode 100644 index 00000000000..83b38054d77 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/privateConstructors/captured.kt @@ -0,0 +1,10 @@ +public open class Outer private constructor(val s: String) { + + companion object { + fun test () = { Outer("OK") }() + } +} + +fun box(): String { + return Outer.test().s +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/privateConstructors/companion.kt b/backend.native/tests/external/codegen/blackbox/privateConstructors/companion.kt new file mode 100644 index 00000000000..482c81233a4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/privateConstructors/companion.kt @@ -0,0 +1,11 @@ +// See also KT-6299 +public open class Outer private constructor() { + companion object { + fun foo() = Outer() + } +} + +fun box(): String { + val outer = Outer.foo() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/privateConstructors/inline.kt b/backend.native/tests/external/codegen/blackbox/privateConstructors/inline.kt new file mode 100644 index 00000000000..9b80c07d05a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/privateConstructors/inline.kt @@ -0,0 +1,11 @@ +// See also KT-6299 +public open class Outer private constructor() { + companion object { + internal inline fun foo() = Outer() + } +} + +fun box(): String { + val outer = Outer.foo() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/privateConstructors/inner.kt b/backend.native/tests/external/codegen/blackbox/privateConstructors/inner.kt new file mode 100644 index 00000000000..16c1734f08f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/privateConstructors/inner.kt @@ -0,0 +1,15 @@ +// See also KT-6299 +public open class Outer private constructor(val s: String) { + inner class Inner: Outer("O") { + fun foo(): String { + return this.s + this@Outer.s + } + } + class Nested: Outer("K") + fun bar() = Inner() +} + +fun box(): String { + val inner = Outer.Nested().bar() + return inner.foo() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/privateConstructors/kt4860.kt b/backend.native/tests/external/codegen/blackbox/privateConstructors/kt4860.kt new file mode 100644 index 00000000000..8b63d2b415f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/privateConstructors/kt4860.kt @@ -0,0 +1,12 @@ +open class A private constructor() { + companion object : A() { + } + + class B: A() +} + +fun box(): String { + val a = A + val b = A.B() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/privateConstructors/secondary.kt b/backend.native/tests/external/codegen/blackbox/privateConstructors/secondary.kt new file mode 100644 index 00000000000..6f59e0474b1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/privateConstructors/secondary.kt @@ -0,0 +1,9 @@ +// See also KT-6299 +public open class Outer private constructor(val x: Int) { + constructor(): this(42) +} + +fun box(): String { + val outer = Outer() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/privateConstructors/synthetic.kt b/backend.native/tests/external/codegen/blackbox/privateConstructors/synthetic.kt new file mode 100644 index 00000000000..5b00a7166da --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/privateConstructors/synthetic.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +// private constructors are transformed into synthetic +class PrivateConstructor private constructor() { + class Nested { val a = PrivateConstructor() } +} + +fun check(klass: Class<*>) { + var hasSynthetic = false + var hasSimple = false + for (method in klass.getDeclaredConstructors()) { + if (method.isSynthetic()) { + hasSynthetic = true + } + else { + hasSimple = true + } + } + if (hasSynthetic && hasSimple) return + throw AssertionError("Class should have both synthetic and non-synthetic constructor: ($hasSynthetic, $hasSimple)") +} + +fun box(): String { + check(PrivateConstructor::class.java) + // Also check that synthetic accessors really work + PrivateConstructor.Nested() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/privateConstructors/withArguments.kt b/backend.native/tests/external/codegen/blackbox/privateConstructors/withArguments.kt new file mode 100644 index 00000000000..a53517a81dd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/privateConstructors/withArguments.kt @@ -0,0 +1,13 @@ +// See also KT-6299 +public open class Outer private constructor(val s: String, val f: Boolean = true) { + class Inner: Outer("xyz") + class Other: Outer("abc", true) + class Another: Outer("", false) +} + +fun box(): String { + val outer = Outer.Inner() + val other = Outer.Other() + val another = Outer.Another() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/privateConstructors/withDefault.kt b/backend.native/tests/external/codegen/blackbox/privateConstructors/withDefault.kt new file mode 100644 index 00000000000..cb96e8dcb4b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/privateConstructors/withDefault.kt @@ -0,0 +1,11 @@ +// See also KT-6299 +public open class Outer private constructor(val x: Int = 0) { + class Inner: Outer() + class Other: Outer(42) +} + +fun box(): String { + val outer = Outer.Inner() + val other = Outer.Other() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/privateConstructors/withLinkedClasses.kt b/backend.native/tests/external/codegen/blackbox/privateConstructors/withLinkedClasses.kt new file mode 100644 index 00000000000..ff7f86f847a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/privateConstructors/withLinkedClasses.kt @@ -0,0 +1,12 @@ +// See also KT-6299 +public open class Outer private constructor(val p: Outer?) { + object First: Outer(null) + class Other(p: Outer = First): Outer(p) +} + +fun box(): String { + val second = Outer.Other() + val third = Outer.Other(second) + val fourth = Outer.Other(third) + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/privateConstructors/withLinkedObjects.kt b/backend.native/tests/external/codegen/blackbox/privateConstructors/withLinkedObjects.kt new file mode 100644 index 00000000000..549e13912ef --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/privateConstructors/withLinkedObjects.kt @@ -0,0 +1,13 @@ +// See also KT-6299 +public open class Outer private constructor(val p: Outer?) { + object Inner: Outer(null) + object Other: Outer(Inner) + object Another: Outer(Other) +} + +fun box(): String { + val outer = Outer.Inner + val other = Outer.Other + val another = Outer.Another + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/privateConstructors/withVarargs.kt b/backend.native/tests/external/codegen/blackbox/privateConstructors/withVarargs.kt new file mode 100644 index 00000000000..f7791f1968c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/privateConstructors/withVarargs.kt @@ -0,0 +1,13 @@ +// See also KT-6299 +public open class Outer private constructor(val s: String, vararg i: Int) { + class Inner: Outer("xyz") + class Other: Outer("abc", 1, 2, 3) + class Another: Outer("", 42) +} + +fun box(): String { + val outer = Outer.Inner() + val other = Outer.Other() + val another = Outer.Another() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/accessToPrivateProperty.kt b/backend.native/tests/external/codegen/blackbox/properties/accessToPrivateProperty.kt new file mode 100644 index 00000000000..b898fa5689e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/accessToPrivateProperty.kt @@ -0,0 +1,52 @@ +class A { + private var foo = 1 + get() { + return 1 + } + + fun foo() { + foo = 5 + foo + } +} + +class B { + private val foo = 1 + get + + fun foo() { + foo + } +} + +class C { + private var foo = 1 + get + set + + fun foo() { + foo = 2 + foo + } +} + +class D { + private var foo = 1 + set(i: Int) { + field = i + 1 + } + + fun foo() { + foo = 5 + foo + } +} + +fun box(): String { + A().foo() + B().foo() + C().foo() + D().foo() + return "OK" +} + diff --git a/backend.native/tests/external/codegen/blackbox/properties/accessToPrivateSetter.kt b/backend.native/tests/external/codegen/blackbox/properties/accessToPrivateSetter.kt new file mode 100644 index 00000000000..adffd830622 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/accessToPrivateSetter.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class D { + var foo = 1 + private set + + fun foo() { + foo = 2 + } +} + +fun box(): String { + D().foo() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/augmentedAssignmentsAndIncrements.kt b/backend.native/tests/external/codegen/blackbox/properties/augmentedAssignmentsAndIncrements.kt new file mode 100644 index 00000000000..0b8af84ffe1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/augmentedAssignmentsAndIncrements.kt @@ -0,0 +1,147 @@ +// Enable when KT-14833 is fixed. +// TARGET_BACKEND: JS +import kotlin.reflect.KProperty + +var a = 0 + +var b: Int + get() = a + set(v: Int) { + a = v + } + +class A { + var c: Int + get() = a + set(v: Int) { + a = v + } +} + +var A.d: Int + get() = a + set(v: Int) { + a = v + } + +var Int.e: Int + get() = a + set(v: Int) { + a = v + } + +object SimpleDelegate { + operator fun getValue(thisRef: Any?, desc: KProperty<*>): Int { + return a + } + + operator fun setValue(thisRef: Any?, desc: KProperty<*>, value: Int) { + a = value + } +} + +var f by SimpleDelegate + +fun box(): String { + if (b++ != 0) return "fail b++: $b" + if (++b != 2) return "fail ++b: $b" + if (--b != 1) return "fail --b: $b" + if (b-- != 1) return "fail b--: $b" + b += 10 + if (b != 10) return "fail b +=: $b" + b *= 10 + if (b != 100) return "fail b *=: $b" + b /= 5 + if (b != 20) return "fail b /=: $b" + b -= 10 + if (b != 10) return "fail b -=: $b" + b %= 7 + if (b != 3) return "fail b %=: $b" + + var q = A() + + a = 0 + if (q.c++ != 0) return "fail q.c++: ${q.c}" + if (++q.c != 2) return "fail ++q.c: ${q.c}" + if (--q.c != 1) return "fail --q.c: ${q.c}" + if (q.c-- != 1) return "fail q.c--: ${q.c}" + q.c += 10 + if (q.c != 10) return "fail q.c +=: ${q.c}" + q.c *= 10 + if (q.c != 100) return "fail q.c *=: ${q.c}" + q.c /= 5 + if (q.c != 20) return "fail q.c /=: ${q.c}" + q.c -= 10 + if (q.c != 10) return "fail q.c -=: ${q.c}" + q.c %= 7 + if (q.c != 3) return "fail q.c %=: ${q.c}" + + a = 0 + if (q.d++ != 0) return "fail q.d++: ${q.d}" + if (++q.d != 2) return "fail ++q.d: ${q.d}" + if (--q.d != 1) return "fail --q.d: ${q.d}" + if (q.d-- != 1) return "fail q.d--: ${q.d}" + q.d += 10 + if (q.d != 10) return "fail q.d +=: ${q.d}" + q.d *= 10 + if (q.d != 100) return "fail q.d *=: ${q.d}" + q.d /= 5 + if (q.d != 20) return "fail q.d /=: ${q.d}" + q.d -= 10 + if (q.d != 10) return "fail q.d -=: ${q.d}" + q.d %= 7 + if (q.d != 3) return "fail q.d %=: ${q.d}" + + a = 0 + if (0.e++ != 0) return "fail 0.e++: ${0.e}" + if (++0.e != 2) return "fail ++0.e: ${0.e}" + if (--0.e != 1) return "fail --0.e: ${0.e}" + if (0.e-- != 1) return "fail 0.e--: ${0.e}" + 0.e += 10 + if (0.e != 10) return "fail 0.e +=: ${0.e}" + 0.e *= 10 + if (0.e != 100) return "fail 0.e *=: ${0.e}" + 0.e /= 5 + if (0.e != 20) return "fail 0.e /=: ${0.e}" + 0.e -= 10 + if (0.e != 10) return "fail 0.e -=: ${0.e}" + 0.e %= 7 + if (0.e != 3) return "fail 0.e %=: ${0.e}" + + a = 0 + if (f++ != 0) return "fail f++: $f" + if (++f != 2) return "fail ++f: $f" + if (--f != 1) return "fail --f: $f" + if (f-- != 1) return "fail f--: $f" + f += 10 + if (f != 10) return "fail f +=: $f" + f *= 10 + if (f != 100) return "fail f *=: $f" + f /= 5 + if (f != 20) return "fail f /=: $f" + f -= 10 + if (f != 10) return "fail f -=: $f" + f %= 7 + if (f != 3) return "fail f %=: $f" + + + var g by SimpleDelegate + + a = 0 + if (g++ != 0) return "fail g++: $g" + if (++g != 2) return "fail ++g: $g" + if (--g != 1) return "fail --g: $g" + if (g-- != 1) return "fail g--: $g" + g += 10 + if (g != 10) return "fail g +=: $g" + g *= 10 + if (g != 100) return "fail g *=: $g" + g /= 5 + if (g != 20) return "fail g /=: $g" + g -= 10 + if (g != 10) return "fail g -=: $g" + g %= 7 + if (g != 3) return "fail g %=: $g" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/classArtificialFieldInsideNested.kt b/backend.native/tests/external/codegen/blackbox/properties/classArtificialFieldInsideNested.kt new file mode 100644 index 00000000000..a33fcca3c74 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/classArtificialFieldInsideNested.kt @@ -0,0 +1,15 @@ +abstract class Your { + abstract val your: String + + fun foo() = your +} + +class My { + val back = "O" + val my: String + get() = object : Your() { + override val your = back + }.foo() + "K" +} + +fun box() = My().my \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/classFieldInsideLambda.kt b/backend.native/tests/external/codegen/blackbox/properties/classFieldInsideLambda.kt new file mode 100644 index 00000000000..121ac3426b4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/classFieldInsideLambda.kt @@ -0,0 +1,6 @@ +class My { + val my: String = "O" + get() = { field }() + "K" +} + +fun box() = My().my \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/classFieldInsideLocalInSetter.kt b/backend.native/tests/external/codegen/blackbox/properties/classFieldInsideLocalInSetter.kt new file mode 100644 index 00000000000..e6e1c9f17f4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/classFieldInsideLocalInSetter.kt @@ -0,0 +1,18 @@ +class My { + var my: String = "U" + get() = { field }() + set(arg) { + class Local { + fun foo() { + field = arg + "K" + } + } + Local().foo() + } +} + +fun box(): String { + val m = My() + m.my = "O" + return m.my +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/classFieldInsideNested.kt b/backend.native/tests/external/codegen/blackbox/properties/classFieldInsideNested.kt new file mode 100644 index 00000000000..0ac00ddb630 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/classFieldInsideNested.kt @@ -0,0 +1,14 @@ +abstract class Your { + abstract val your: String + + fun foo() = your +} + +class My { + val my: String = "O" + get() = object : Your() { + override val your = field + }.foo() + "K" +} + +fun box() = My().my \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/classObjectProperties.kt b/backend.native/tests/external/codegen/blackbox/properties/classObjectProperties.kt new file mode 100644 index 00000000000..1a48f5eb5f4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/classObjectProperties.kt @@ -0,0 +1,58 @@ +class Test { + + companion object { + + public val prop1 : Int = 10 + + public var prop2 : Int = 11 + private set + + public val prop3: Int = 12 + get() { + return field + } + + var prop4 : Int = 13 + + fun incProp4() { + prop4++ + } + + + public var prop5 : Int = 14 + + public var prop7 : Int = 20 + set(i: Int) { + field++ + } + } + +} + + +fun box(): String { + val t = Test; + + if (t.prop1 != 10) return "fail1"; + + if (t.prop2 != 11) return "fail2"; + + if (t.prop3 != 12) return "fail3"; + + if (t.prop4 != 13) return "fail4"; + + t.incProp4() + if (t.prop4 != 14) return "fail4.inc"; + + if (t.prop5 != 14) return "fail5"; + + t.prop5 = 1414 + if (t.prop5 != 1414) return "fail6"; + + if (t.prop7 != 20) return "fail7"; + + t.prop7 = 1000000 + if (t.prop7 != 21) return "fail8"; + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/classPrivateArtificialFieldInsideNested.kt b/backend.native/tests/external/codegen/blackbox/properties/classPrivateArtificialFieldInsideNested.kt new file mode 100644 index 00000000000..af1660a58da --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/classPrivateArtificialFieldInsideNested.kt @@ -0,0 +1,15 @@ +abstract class Your { + abstract val your: String + + fun foo() = your +} + +class My { + private val back = "O" + val my: String + get() = object : Your() { + override val your = back + }.foo() + "K" +} + +fun box() = My().my \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/collectionSize.kt b/backend.native/tests/external/codegen/blackbox/properties/collectionSize.kt new file mode 100644 index 00000000000..6a296b7fd69 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/collectionSize.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: Test.java + +public class Test extends java.util.ArrayList { + public final int size() { + return 56; + } +} + +// FILE: test.kt + +class OurTest : Test() + +fun box(): String { + val t = OurTest() + val x: MutableCollection = t + + if (t.size != 56) return "fail 1: ${t.size}" + if (x.size != 56) return "fail 1: ${x.size}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/commonPropertiesKJK.kt b/backend.native/tests/external/codegen/blackbox/properties/commonPropertiesKJK.kt new file mode 100644 index 00000000000..264d2ffbdfc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/commonPropertiesKJK.kt @@ -0,0 +1,112 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: J.java + +public class J extends A { + + public boolean okField = false; + + public int getValProp() { + return 123; + } + + public int getVarProp() { + return 456; + } + + public void setVarProp(int x) { + okField = true; + } + + public int isProp() { + return 789; + } + + public void setProp(int x) { + okField = true; + } +} + +// FILE: test.kt + +open class A { + open val valProp: Int = -1 + open var varProp: Int = -1 + open var isProp: Int = -1 +} + +class B : J() { + override val valProp: Int = super.valProp + 1 + override var varProp: Int + set(value) { + super.varProp = value + } + get() = super.varProp + 1 + + override var isProp: Int + set(value) { + super.isProp = value + } + get() = super.isProp + 1 +} + +fun box(): String { + val j = J() + var a: A = j + + if (j.valProp != 123) return "fail 1" + if (a.valProp != 123) return "fail 2" + + j.varProp = -1 + if (!j.okField) return "fail 3" + j.okField = false + + a.varProp = -1 + if (!j.okField) return "fail 4" + j.okField = false + + if (j.varProp != 456) return "fail 5" + if (a.varProp != 456) return "fail 6" + + j.isProp = -1 + if (!j.okField) return "fail 7" + j.okField = false + + a.isProp = -1 + if (!j.okField) return "fail 8" + j.okField = false + + if (j.isProp != 789) return "fail 9" + if (a.isProp != 789) return "fail 10" + + val b = B() + a = b + + if (b.valProp != 124) return "fail 11" + if (a.valProp != 124) return "fail 12" + + b.varProp = -1 + if (!b.okField) return "fail 13" + b.okField = false + + a.varProp = -1 + if (!b.okField) return "fail 14" + b.okField = false + + if (b.varProp != 457) return "fail 15" + if (a.varProp != 457) return "fail 16" + + b.isProp = -1 + if (!b.okField) return "fail 17" + b.okField = false + + a.isProp = -1 + if (!b.okField) return "fail 18" + b.okField = false + + if (b.isProp != 790) return "fail 19" + if (a.isProp != 790) return "fail 20" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/companionFieldInsideLambda.kt b/backend.native/tests/external/codegen/blackbox/properties/companionFieldInsideLambda.kt new file mode 100644 index 00000000000..4e4f60b9df7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/companionFieldInsideLambda.kt @@ -0,0 +1,8 @@ +class My { + companion object { + val my: String = "O" + get() = { field }() + "K" + } +} + +fun box() = My.my \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/companionObjectAccessor.kt b/backend.native/tests/external/codegen/blackbox/properties/companionObjectAccessor.kt new file mode 100644 index 00000000000..85f734aa294 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/companionObjectAccessor.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: J.java + +public class J { + public static int f() { + return A.Companion.getI1() + A.Companion.getI2() + B.Named.getI1() + B.Named.getI2(); + } +} + +// FILE: test.kt + +class A { + companion object { + val i1 = 1 + val i2 = 2 + } +} + +class B { + companion object Named { + val i1 = 3 + val i2 = 4 + } +} + +fun box(): String { + return if (J.f() == A.i1 + A.i2 + B.i1 + B.i2) "OK" else "Fail: ${J.f()}" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/companionObjectPropertiesFromJava.kt b/backend.native/tests/external/codegen/blackbox/properties/companionObjectPropertiesFromJava.kt new file mode 100644 index 00000000000..6ae3b092564 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/companionObjectPropertiesFromJava.kt @@ -0,0 +1,53 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Test.java + +class Test { + String test() { + String s; + + s = Klass.NAME; + if (!s.equals("Klass")) throw new AssertionError("Fail class: " + s); + + s = Klass.JVM_NAME; + if (!s.equals("JvmKlass")) throw new AssertionError("Fail jvm class: " + s); + + s = Trait.NAME; + if (!s.equals("Trait")) throw new AssertionError("Fail interface: " + s); + + s = Enoom.NAME; + if (!s.equals("Enum")) throw new AssertionError("Fail enum: " + s); + + s = Enoom.JVM_NAME; + if (!s.equals("JvmEnum")) throw new AssertionError("Fail jvm enum: " + s); + + return "OK"; + } +} + +// FILE: test.kt + +class Klass { + companion object { + const val NAME = "Klass" + @JvmField val JVM_NAME = "JvmKlass" + } +} + +interface Trait { + companion object { + const val NAME = "Trait" + } +} + +enum class Enoom { + ; + companion object { + const val NAME = "Enum" + @JvmField val JVM_NAME = "JvmEnum" + } +} + +fun box() = Test().test() diff --git a/backend.native/tests/external/codegen/blackbox/properties/companionPrivateField.kt b/backend.native/tests/external/codegen/blackbox/properties/companionPrivateField.kt new file mode 100644 index 00000000000..7a4b94e7aaa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/companionPrivateField.kt @@ -0,0 +1,10 @@ +class My { + companion object { + private val my: String = "O" + get() = field + "K" + + fun getValue() = my + } +} + +fun box() = My.getValue() \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/companionPrivateFieldInsideLambda.kt b/backend.native/tests/external/codegen/blackbox/properties/companionPrivateFieldInsideLambda.kt new file mode 100644 index 00000000000..7219fcd4d3d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/companionPrivateFieldInsideLambda.kt @@ -0,0 +1,10 @@ +class My { + companion object { + private val my: String = "O" + get() = { field }() + "K" + + fun getValue() = my + } +} + +fun box() = My.getValue() \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/const/constFlags.kt b/backend.native/tests/external/codegen/blackbox/properties/const/constFlags.kt new file mode 100644 index 00000000000..a031c4d0341 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/const/constFlags.kt @@ -0,0 +1,52 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +@file:JvmName("XYZ") +import java.lang.reflect.Modifier + +private const val privateConst: Int = 1 +public const val publicConst: Int = 3 + +public object A { + private const val privateConst: Int = 1 + public const val publicConst: Int = 3 +} + +public class B { + companion object { + private const val privateConst: Int = 1 + protected const val protectedConst: Int = 2 + public const val publicConst: Int = 3 + } +} + +fun check(clazz: Class<*>, expectProtected: Boolean = true) { + val fields = clazz.declaredFields.filter { it.name.contains("Const") } + + assert(fields.all { Modifier.isStatic(it.modifiers) }) { "`$clazz` contains non-static fields" } + + assert(Modifier.isPrivate(fields.single { it.name.contains("private") }.modifiers)) { + "`$clazz`.privateConst is not private" + } + + assert(Modifier.isPublic(fields.single { it.name.contains("public") }.modifiers)) { + "`$clazz`.publicConst is not public" + } + + if (expectProtected) { + assert(Modifier.isProtected(fields.single { it.name.contains("protected") }.modifiers)) { + "`$clazz`.protectedConst is not protected" + } + } +} + +fun box(): String { + check(A::class.java, false) + check(B::class.java) + check(Class.forName("XYZ"), false) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/const/constValInAnnotationDefault.kt b/backend.native/tests/external/codegen/blackbox/properties/const/constValInAnnotationDefault.kt new file mode 100644 index 00000000000..f02f2bd6ca7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/const/constValInAnnotationDefault.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +const val z = "OK" + +annotation class A(val value: String = z) + +@A +class Test + +fun box(): String { + return Test::class.java.getAnnotation(A::class.java).value +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/const/interfaceCompanion.kt b/backend.native/tests/external/codegen/blackbox/properties/const/interfaceCompanion.kt new file mode 100644 index 00000000000..afa9670a227 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/const/interfaceCompanion.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +interface KInt { + + companion object { + const val a = "a" + const val b = "b$a" + } +} + +fun box(): String { + val a = KInt::class.java.getField("a").get(null) + val b = KInt::class.java.getField("b").get(null) + + if (a !== KInt.a) return "fail 1: KInt.a !== KInt.Companion.a" + if (b !== KInt.b) return "fail 2: KInt.b !== KInt.Companion.b" + if (b !== "ba") return "fail 2: 'ba' !== KInt.Companion.b" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/field.kt b/backend.native/tests/external/codegen/blackbox/properties/field.kt new file mode 100644 index 00000000000..c03066671ad --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/field.kt @@ -0,0 +1,10 @@ +var my: String = "" + get() = field + "K" + set(arg) { + field = arg + } + +fun box(): String { + my = "O" + return my +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/fieldInClass.kt b/backend.native/tests/external/codegen/blackbox/properties/fieldInClass.kt new file mode 100644 index 00000000000..37ef0a06a9a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/fieldInClass.kt @@ -0,0 +1,6 @@ +class My { + val my: String = "O" + get() = field + "K" +} + +fun box() = My().my diff --git a/backend.native/tests/external/codegen/blackbox/properties/fieldInsideField.kt b/backend.native/tests/external/codegen/blackbox/properties/fieldInsideField.kt new file mode 100644 index 00000000000..e86fe70da9e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/fieldInsideField.kt @@ -0,0 +1,13 @@ +abstract class Your { + abstract val your: String + + fun foo() = your +} + +val my: String = "O" + get() = field + object: Your() { + override val your = "K" + get() = field + }.foo() + +fun box() = my \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/fieldInsideLambda.kt b/backend.native/tests/external/codegen/blackbox/properties/fieldInsideLambda.kt new file mode 100644 index 00000000000..ebf3cb6cfb7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/fieldInsideLambda.kt @@ -0,0 +1,4 @@ +val my: String = "O" + get() = { field }() + "K" + +fun box() = my diff --git a/backend.native/tests/external/codegen/blackbox/properties/fieldInsideNested.kt b/backend.native/tests/external/codegen/blackbox/properties/fieldInsideNested.kt new file mode 100644 index 00000000000..cb49c6b46c7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/fieldInsideNested.kt @@ -0,0 +1,12 @@ +abstract class Your { + abstract val your: String + + fun foo() = your +} + +val my: String = "O" + get() = object: Your() { + override val your = field + }.foo() + "K" + +fun box() = my \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/fieldSimple.kt b/backend.native/tests/external/codegen/blackbox/properties/fieldSimple.kt new file mode 100644 index 00000000000..be19a1f8d45 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/fieldSimple.kt @@ -0,0 +1,4 @@ +val x: String = "OK" + get() = field + +fun box() = x \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/generalAccess.kt b/backend.native/tests/external/codegen/blackbox/properties/generalAccess.kt new file mode 100644 index 00000000000..577d9ab7e13 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/generalAccess.kt @@ -0,0 +1,54 @@ +package As + +val staticProperty : String = "1" + +val String.staticExt: String get() = "1" + +open class A(val init: String) { + + open val property : String = init + + private val privateProperty : String = init + + val String.ext: String get() = "1" + + val Int.myInc : Int + get() = this + 1 + + open fun getPrivate() : String { + return privateProperty; + } + + open fun getExt() : String { + return "0".ext; + } + + public var backingField : Int = 0 + get() = field.myInc + set(s) { field = s } + +} + +open class B(init: String) : A("1") { + + override val property: String = init + + fun getOpenProperty(): String { + return super.property + } + + fun getWithBackingFieldProperty(): String { + return property + } +} + +fun box() : String { + val a = A("1"); + val b = B("0"); + a.backingField = 0 + val result = a.property + a.getPrivate() + staticProperty + "0".staticExt + a.getExt() + + a.backingField + a.backingField + + b.getOpenProperty() + b.property + b.getWithBackingFieldProperty() + + return if (result == "1111111100") "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/javaPropertyBoxedGetter.kt b/backend.native/tests/external/codegen/blackbox/properties/javaPropertyBoxedGetter.kt new file mode 100644 index 00000000000..88f00bb32e3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/javaPropertyBoxedGetter.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: JavaClass.java + +public class JavaClass { + + private Boolean value; + + public Boolean isValue() { + return value; + } + + public void setValue(boolean value) { + this.value = value; + } +} + +// FILE: kotlin.kt + +fun box(): String { + val javaClass = JavaClass() + + if (javaClass.isValue != null) return "fail 1" + + javaClass.isValue = false + if (javaClass.isValue != false) return "fail 2" + + javaClass.isValue = true + if (javaClass.isValue != true) return "fail 3" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/javaPropertyBoxedSetter.kt b/backend.native/tests/external/codegen/blackbox/properties/javaPropertyBoxedSetter.kt new file mode 100644 index 00000000000..35dca43aa8d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/javaPropertyBoxedSetter.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: JavaClass.java + +public class JavaClass { + + private boolean value; + + public boolean isValue() { + return value; + } + + public void setValue(Boolean value) { + this.value = value; + } +} + +// FILE: kotlin.kt + +fun box(): String { + val javaClass = JavaClass() + + if (javaClass.isValue != false) return "fail 1" + + javaClass.isValue = true + + if (javaClass.isValue != true) return "fail 2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt10715.kt b/backend.native/tests/external/codegen/blackbox/properties/kt10715.kt new file mode 100644 index 00000000000..7449c1b5bfa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt10715.kt @@ -0,0 +1,17 @@ +fun box(): String { + var a = Base() + + val count = a.count + if (count != 0) return "fail 1: $count" + + val count2 = a.count + if (count2 != 1) return "fail 2: $count2" + + return "OK" + +} + +class Base { + var count: Int = 0 + get() = field++ +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt10729.kt b/backend.native/tests/external/codegen/blackbox/properties/kt10729.kt new file mode 100644 index 00000000000..9b0db522f25 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt10729.kt @@ -0,0 +1,20 @@ +class IntentionsBundle { + companion object { + fun message(key: String): String { + return key + BUNDLE + } + + fun message2(key: String): String { + return { key + BUNDLE }() + } + + private const val BUNDLE = "K" + } +} + + +fun box(): String { + if (IntentionsBundle.message("O") != "OK") return "fail 1: ${IntentionsBundle.message("O")}" + + return IntentionsBundle.message2("O") +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt1159.kt b/backend.native/tests/external/codegen/blackbox/properties/kt1159.kt new file mode 100644 index 00000000000..66b07250a72 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt1159.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +public object RefreshQueue { + + private val any = Any() + + private val workerThread: Thread = Thread(object : Runnable { + override fun run() { + any.hashCode() + } + }); + + init { + workerThread.start() + } +} + +fun box() : String { + RefreshQueue + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt1165.kt b/backend.native/tests/external/codegen/blackbox/properties/kt1165.kt new file mode 100644 index 00000000000..0a32a58b9e2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt1165.kt @@ -0,0 +1,13 @@ +public abstract class VirtualFile() { + public abstract val size : Long +} + +public class PhysicalVirtualFile : VirtualFile() { + public override val size: Long + get() = 11 +} + +fun box() : String { + PhysicalVirtualFile() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt1168.kt b/backend.native/tests/external/codegen/blackbox/properties/kt1168.kt new file mode 100644 index 00000000000..fc931784687 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt1168.kt @@ -0,0 +1,15 @@ +public abstract class BaseClass() { + protected abstract val kind : String + + protected open val kind2 : String = " kind1" + + fun debug() = kind + kind2 +} + +public class Subclass : BaseClass() { + override val kind : String = "Physical" + + override val kind2 : String = " kind2" +} + +fun box():String = if(Subclass().debug() == "Physical kind2") "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt1170.kt b/backend.native/tests/external/codegen/blackbox/properties/kt1170.kt new file mode 100644 index 00000000000..3b33740d7c6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt1170.kt @@ -0,0 +1,16 @@ +public abstract class BaseClass() { + open val kind : String = "BaseClass " + + fun getKindValue() : String { + return kind + } +} + +public class Subclass : BaseClass() { + override val kind : String = "Subclass " +} + +fun box(): String { + val r = Subclass().getKindValue() + Subclass().kind + return if(r == "Subclass Subclass ") "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt12200.kt b/backend.native/tests/external/codegen/blackbox/properties/kt12200.kt new file mode 100644 index 00000000000..8d27165bb25 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt12200.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +//WITH_RUNTIME + +class ThingTemplate { + val prop = 0 +} + +class ThingVal(template: ThingTemplate) { + val prop = template.prop +} + +class ThingVar(template: ThingTemplate) { + var prop = template.prop +} + + +fun box() : String { + val template = ThingTemplate(); + val javaClass = ThingTemplate::class.java + val field = javaClass.getDeclaredField("prop")!! + field.isAccessible = true + field.set(template, 1) + + val thingVal = ThingVal(template) + if (thingVal.prop != 1) return "fail 1" + + val thingVar = ThingVar(template) + if (thingVar.prop != 1) return "fail 2" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt1398.kt b/backend.native/tests/external/codegen/blackbox/properties/kt1398.kt new file mode 100644 index 00000000000..b3b3f69c1ca --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt1398.kt @@ -0,0 +1,10 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +open class Base(val bar: String) + +class Foo(bar: String) : Base(bar) { + fun something() = (bar as java.lang.String).toUpperCase() +} + +fun box() = Foo("ok").something() diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt1417.kt b/backend.native/tests/external/codegen/blackbox/properties/kt1417.kt new file mode 100644 index 00000000000..665f45d22cd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt1417.kt @@ -0,0 +1,9 @@ +package pack + +open class A(val value: String ) + +class B(value: String) : A(value) { + override fun toString() = "B($value)"; +} + +fun box() = if (B("4").toString() == "B(4)") "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt1482_2279.kt b/backend.native/tests/external/codegen/blackbox/properties/kt1482_2279.kt new file mode 100644 index 00000000000..5ea5c172005 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt1482_2279.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +abstract class ClassValAbstract { + abstract var a: Int + + companion object { + val methods = (this as java.lang.Object).getClass()?.getClassLoader()?.loadClass("ClassValAbstract")?.getMethods()!! + } +} + +fun box() : String { + for(m in ClassValAbstract.methods) { + if (m!!.getName() == "getA") { + if(m!!.getModifiers() != 1025) + return "get failed" + } + if (m!!.getName() == "setA") { + if(m!!.getModifiers() != 1025) + return "set failed" + } + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt1714.kt b/backend.native/tests/external/codegen/blackbox/properties/kt1714.kt new file mode 100644 index 00000000000..9425908610e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt1714.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +interface A { + val method : (() -> Unit )? + val test : Integer +} + +class AImpl : A { + override val method : (() -> Unit )? = { + } + override val test : Integer = Integer(777) +} + +fun test(a : A) { + val method = a.method + if (method != null) { + method() + } +} + +public fun box() : String { + AImpl().test + test(AImpl()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt1714_minimal.kt b/backend.native/tests/external/codegen/blackbox/properties/kt1714_minimal.kt new file mode 100644 index 00000000000..faec0d99269 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt1714_minimal.kt @@ -0,0 +1,13 @@ +interface A { + val v: Int +} + +class AImpl : A { + override val v: Int = 5 +} + +public fun box() : String { + val a: A = AImpl() + a.v + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt1892.kt b/backend.native/tests/external/codegen/blackbox/properties/kt1892.kt new file mode 100644 index 00000000000..ae564c7fc93 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt1892.kt @@ -0,0 +1,5 @@ +val Int.ext: () -> Int get() = { 5 } +val Long.ext: Long get() = 4.ext().toLong() //(c.kt:4) +val y: Long get() = 10L.ext + +fun box(): String = if (y == 5L) "OK" else "fail: $y" diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt2331.kt b/backend.native/tests/external/codegen/blackbox/properties/kt2331.kt new file mode 100644 index 00000000000..a96dd67bf6d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt2331.kt @@ -0,0 +1,14 @@ +class P { + var x : Int = 0 + private set + + fun foo() { + ({ x = 4 })() + } +} + +fun box() : String { + val p = P() + p.foo() + return if (p.x == 4) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt257.kt b/backend.native/tests/external/codegen/blackbox/properties/kt257.kt new file mode 100644 index 00000000000..299042d2f31 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt257.kt @@ -0,0 +1,20 @@ +class A(var t: T) {} +class B(val r: R) {} + +fun box() : String { + val ai = A(1) + val aai = A>(ai) + if(aai.t.t != 1) return "fail" +/* + aai.t.t = 2 + if(aai.t.t != 2) return "fail" + + if(ai.t != 2) return "fail" + if(aai.t != ai) return "fail" + if(aai.t !== ai) return "fail" + + val abi = A>(B(1)) + if(abi.t.r != 1) return "fail" +*/ + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt2655.kt b/backend.native/tests/external/codegen/blackbox/properties/kt2655.kt new file mode 100644 index 00000000000..3956fb3a17d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt2655.kt @@ -0,0 +1,20 @@ +interface TextField { + fun getText(): String + fun setText(text: String) +} + +class SimpleTextField : TextField { + private var text2 = "" + override fun getText() = text2 + override fun setText(text: String) { + this.text2 = text + } +} + +class TextFieldWrapper(textField: TextField) : TextField by textField + +fun box() : String { + val textField = TextFieldWrapper(SimpleTextField()) + textField.setText("OK") + return textField.getText() +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt2786.kt b/backend.native/tests/external/codegen/blackbox/properties/kt2786.kt new file mode 100644 index 00000000000..003ca536275 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt2786.kt @@ -0,0 +1,13 @@ +interface FooTrait { + val propertyTest: String +} + +class FooDelegate: FooTrait { + override val propertyTest: String = "OK" +} + +class DelegateTest(): FooTrait by FooDelegate() { + fun test() = propertyTest +} + +fun box() = DelegateTest().test() diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt2892.kt b/backend.native/tests/external/codegen/blackbox/properties/kt2892.kt new file mode 100644 index 00000000000..816b11009d7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt2892.kt @@ -0,0 +1,16 @@ +open class A +class B : A() { + fun foo() = 1 +} + +class Test { + val a : A = B() + private val b : B get() = a as B //'private' is important here + + fun outer() : Int { + fun inner() : Int = b.foo() //'no such field error' here + return inner() + } +} + +fun box() = if (Test().outer() == 1) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt3118.kt b/backend.native/tests/external/codegen/blackbox/properties/kt3118.kt new file mode 100644 index 00000000000..b95ea4ad3b4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt3118.kt @@ -0,0 +1,12 @@ +package testing + +class Test { + private val hello: String + get() { return "hello" } + + fun sayHello() : String = hello +} + +fun box(): String { + return if (Test().sayHello() == "hello") "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt3524.kt b/backend.native/tests/external/codegen/blackbox/properties/kt3524.kt new file mode 100644 index 00000000000..3fcdaaebcf1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt3524.kt @@ -0,0 +1,5 @@ +val i: Any = 12 + +fun box(): String { + return if (i == 12) "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt3551.kt b/backend.native/tests/external/codegen/blackbox/properties/kt3551.kt new file mode 100644 index 00000000000..ba6696e1417 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt3551.kt @@ -0,0 +1,23 @@ +class Identifier() { + private var myNullable : Boolean = false + set(l : Boolean) { + //do nothing + } + + fun getValue() : Boolean { + return myNullable + } + + companion object { + fun init(isNullable : Boolean) : Identifier { + val id = Identifier() + id.myNullable = isNullable + return id + } + } +} + +fun box() : String { + val id = Identifier.init(true) + return if (id.getValue() == false) return "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt3556.kt b/backend.native/tests/external/codegen/blackbox/properties/kt3556.kt new file mode 100644 index 00000000000..adce0368131 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt3556.kt @@ -0,0 +1,10 @@ +class Test { + val a : String = "1" + private val b : String get() = a + + fun outer() : Int { + return b.length + } +} + +fun box() = if (Test().outer() == 1) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt3930.kt b/backend.native/tests/external/codegen/blackbox/properties/kt3930.kt new file mode 100644 index 00000000000..b03168b7f43 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt3930.kt @@ -0,0 +1,16 @@ +public abstract class Foo { + var isOpen = true + private set +} +public class Bar: Foo() { + inner class Baz { + fun call() { + val s = this@Bar + s.isOpen + } + } +} +fun box(): String { + Bar().Baz() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt4140.kt b/backend.native/tests/external/codegen/blackbox/properties/kt4140.kt new file mode 100644 index 00000000000..55c964df5b8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt4140.kt @@ -0,0 +1,16 @@ +class TestObject() +{ + companion object { + var prop: Int = 1 + get() = field++ + } +} + +fun box(): String { + + if (TestObject.prop != 1) return "fail 1" + + if (TestObject.prop != 2) return "fail 2" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt4252.kt b/backend.native/tests/external/codegen/blackbox/properties/kt4252.kt new file mode 100644 index 00000000000..2780832a23c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt4252.kt @@ -0,0 +1,23 @@ +class CallbackBlock {} + +public class Foo +{ + companion object { + private var bar = 0 + } + + init { + ++bar + } + + fun getBar(): Int = bar +} + +fun box() : String { + + val foo = Foo() + + if (foo.getBar() != 1) return "Fail"; + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt4252_2.kt b/backend.native/tests/external/codegen/blackbox/properties/kt4252_2.kt new file mode 100644 index 00000000000..c86578a72ce --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt4252_2.kt @@ -0,0 +1,30 @@ +class Foo() { + companion object { + val bar = "OK"; + var boo = "FAIL"; + } + + val a = bar + var b = Foo.bar + val c: String + var d: String + + init { + c = bar + d = Foo.bar + boo = "O" + Foo.boo += "K" + } +} + +fun box(): String { + val foo = Foo() + + if (foo.a != "OK") return "foo.a != OK" + if (foo.b != "OK") return "foo.b != OK" + if (foo.c != "OK") return "foo.c != OK" + if (foo.d != "OK") return "foo.d != OK" + if (Foo.boo != "OK") return "Foo.boo != OK" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt4340.kt b/backend.native/tests/external/codegen/blackbox/properties/kt4340.kt new file mode 100644 index 00000000000..63a97eb0f44 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt4340.kt @@ -0,0 +1,36 @@ +class A { + + var result: Int = 0; + + private val Int.times3: Int + get() = this * 3 + + private var Int.times: Int + get() = this * 4 + set(s: Int) { + result = this * s + } + + fun test(p: Int):Int { + return { + p.times3 + }() + } + + fun test2(p: Int, s: Int):Int { + { + p.times = s + }() + return result + } +} + +fun box() : String { + var result = A().test(3); + if (result != 9) return "fail1: $result" + + result = A().test2(2, 4); + if (result != 8) return "fail2: $result" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt4373.kt b/backend.native/tests/external/codegen/blackbox/properties/kt4373.kt new file mode 100644 index 00000000000..41b781f2cfc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt4373.kt @@ -0,0 +1,14 @@ +interface Tr { + val prop: T +} + +class A(a: Tr) : Tr by a + +fun eat(x: Int) {} + +fun box(): String { + eat(A(object : Tr { + override val prop = 42 + }).prop) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt4383.kt b/backend.native/tests/external/codegen/blackbox/properties/kt4383.kt new file mode 100644 index 00000000000..fb6d0a2465f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt4383.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +import kotlin.reflect.KProperty + +class D { + operator fun getValue(a: Any, p: KProperty<*>) { } +} + +object P { + val u = Unit + val v by D() + var w = Unit +} + +fun box(): String { + if (P.u != P.v) return "Fail uv" + P.w = Unit + if (P.w != P.u) return "Fail w" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt613.kt b/backend.native/tests/external/codegen/blackbox/properties/kt613.kt new file mode 100644 index 00000000000..4f55c044844 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt613.kt @@ -0,0 +1,15 @@ +package name + +class Test() { + var i = 5 + val ten = 10.toLong() + + fun Long.t() = this.toInt() + i++ + ++i + + fun tt() = ten.t() +} + +fun box() : String { + var m = Test() + return if((m.i)++ == 5 && ++(m.i) == 7 && m.tt() == 26) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt8928.kt b/backend.native/tests/external/codegen/blackbox/properties/kt8928.kt new file mode 100644 index 00000000000..bafc93f62b3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt8928.kt @@ -0,0 +1,16 @@ +class App { + fun init() { + s = "OK" + } + companion object { + var s: String = "Fail" + private set + + } +} + +fun box(): String { + App().init() + + return App.s +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/kt9603.kt b/backend.native/tests/external/codegen/blackbox/properties/kt9603.kt new file mode 100644 index 00000000000..ddbabfcc99b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/kt9603.kt @@ -0,0 +1,11 @@ +class A { + public var prop = "OK" + private set + + + fun test(): String { + return { prop }() + } +} + +fun box(): String = A().test() \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/lateinit/accessor.kt b/backend.native/tests/external/codegen/blackbox/properties/lateinit/accessor.kt new file mode 100644 index 00000000000..441bc5ec592 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/lateinit/accessor.kt @@ -0,0 +1,20 @@ +public class A { + + fun setMyStr() { + str = "OK" + } + + fun getMyStr(): String { + return str + } + + private companion object { + private lateinit var str: String + } +} + +fun box(): String { + val a = A() + a.setMyStr() + return a.getMyStr() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/lateinit/accessorException.kt b/backend.native/tests/external/codegen/blackbox/properties/lateinit/accessorException.kt new file mode 100644 index 00000000000..d8022a1a2e9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/lateinit/accessorException.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +public class A { + + fun getMyStr(): String { + try { + val a = str + } catch (e: RuntimeException) { + return "OK" + } + + return "FAIL" + } + + private companion object { + private lateinit var str: String + } +} + +fun box(): String { + val a = A() + return a.getMyStr() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/lateinit/exceptionField.kt b/backend.native/tests/external/codegen/blackbox/properties/lateinit/exceptionField.kt new file mode 100644 index 00000000000..7f334665513 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/lateinit/exceptionField.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class A { + private lateinit var str: String + + public fun getMyStr(): String { + try { + val a = str + } catch (e: RuntimeException) { + return "OK" + } + + return "FAIL" + } +} + +fun box(): String { + val a = A() + return a.getMyStr() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/lateinit/exceptionGetter.kt b/backend.native/tests/external/codegen/blackbox/properties/lateinit/exceptionGetter.kt new file mode 100644 index 00000000000..256d16b48fa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/lateinit/exceptionGetter.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class A { + public lateinit var str: String +} + +fun box(): String { + val a = A() + try { + a.str + } catch (e: RuntimeException) { + return "OK" + } + return "FAIL" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/lateinit/override.kt b/backend.native/tests/external/codegen/blackbox/properties/lateinit/override.kt new file mode 100644 index 00000000000..02d05d723be --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/lateinit/override.kt @@ -0,0 +1,21 @@ +interface Intf { + val str: String +} + +class A : Intf { + override lateinit var str: String + + fun setMyStr() { + str = "OK" + } + + fun getMyStr(): String { + return str + } +} + +fun box(): String { + val a = A() + a.setMyStr() + return a.getMyStr() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/lateinit/overrideException.kt b/backend.native/tests/external/codegen/blackbox/properties/lateinit/overrideException.kt new file mode 100644 index 00000000000..8a5f29fcff5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/lateinit/overrideException.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +interface Intf { + val str: String +} + +class A : Intf { + override lateinit var str: String + + fun getMyStr(): String { + try { + val a = str + } catch (e: RuntimeException) { + return "OK" + } + return "FAIL" + } +} + +fun box(): String { + val a = A() + return a.getMyStr() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/lateinit/privateSetter.kt b/backend.native/tests/external/codegen/blackbox/properties/lateinit/privateSetter.kt new file mode 100644 index 00000000000..75bdc125e64 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/lateinit/privateSetter.kt @@ -0,0 +1,12 @@ +class My { + lateinit var x: String + private set + + fun init() { x = "OK" } +} + +fun box(): String { + val my = My() + my.init() + return my.x +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/lateinit/privateSetterFromLambda.kt b/backend.native/tests/external/codegen/blackbox/properties/lateinit/privateSetterFromLambda.kt new file mode 100644 index 00000000000..80baa4ec688 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/lateinit/privateSetterFromLambda.kt @@ -0,0 +1,12 @@ +class My { + lateinit var x: String + private set + + fun init(arg: String, f: (String) -> String) { x = f(arg) } +} + +fun box(): String { + val my = My() + my.init("O") { it + "K" } + return my.x +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/lateinit/simpleVar.kt b/backend.native/tests/external/codegen/blackbox/properties/lateinit/simpleVar.kt new file mode 100644 index 00000000000..b5314ead1c8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/lateinit/simpleVar.kt @@ -0,0 +1,9 @@ +class A { + public lateinit var str: String +} + +fun box(): String { + val a = A() + a.str = "OK" + return a.str +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/lateinit/visibility.kt b/backend.native/tests/external/codegen/blackbox/properties/lateinit/visibility.kt new file mode 100644 index 00000000000..e2ae4d9dc1e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/lateinit/visibility.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +import java.lang.reflect.Modifier + +public class A { + private lateinit var privateField: String + protected lateinit var protectedField: String + public lateinit var publicField: String + + fun test(): String { + val clazz = A::class.java + val cond = arrayListOf() + + if (!Modifier.isPrivate(clazz.getDeclaredField("privateField").modifiers)) cond += "NOT_PRIVATE" + if (!Modifier.isProtected(clazz.getDeclaredField("protectedField").modifiers)) cond += "NOT_PROTECTED" + if (!Modifier.isPublic(clazz.getDeclaredField("publicField").modifiers)) cond += "NOT_PUBLIC" + + try { + val a = privateField + } catch (e: UninitializedPropertyAccessException) { + return if (cond.isEmpty()) "OK" else cond.joinToString() + } + + return "EXCEPTION WAS NOT CAUGHT" + } +} + +fun box(): String { + return A().test() +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/primitiveOverrideDefaultAccessor.kt b/backend.native/tests/external/codegen/blackbox/properties/primitiveOverrideDefaultAccessor.kt new file mode 100644 index 00000000000..e8039fa4cc7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/primitiveOverrideDefaultAccessor.kt @@ -0,0 +1,11 @@ +interface R> { + var value: T +} + +class A(override var value: Int): R + +fun box(): String { + val a = A(239) + a.value = 42 + return if (a.value == 42) "OK" else "Fail 1" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/primitiveOverrideDelegateAccessor.kt b/backend.native/tests/external/codegen/blackbox/properties/primitiveOverrideDelegateAccessor.kt new file mode 100644 index 00000000000..008ef946010 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/primitiveOverrideDelegateAccessor.kt @@ -0,0 +1,20 @@ +import kotlin.reflect.KProperty + +class Holder(var value: Int) { + operator fun getValue(that: Any?, desc: KProperty<*>) = value + operator fun setValue(that: Any?, desc: KProperty<*>, newValue: Int) { value = newValue } +} + +interface R> { + var value: T +} + +class A(start: Int) : R { + override var value: Int by Holder(start) +} + +fun box(): String { + val a = A(239) + a.value = 42 + return if (a.value == 42) "OK" else "Fail 1" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/privatePropertyInConstructor.kt b/backend.native/tests/external/codegen/blackbox/properties/privatePropertyInConstructor.kt new file mode 100644 index 00000000000..9a9e186c8de --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/privatePropertyInConstructor.kt @@ -0,0 +1,18 @@ +class A( + private val x: String, + private var y: Double +) { + fun foo() { + val r = { + if (x != "abc") throw AssertionError("$x") + y = 0.0 + if (y != 0.0) throw AssertionError("$y") + } + r() + } +} + +fun box(): String { + A("abc", 3.14).foo() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/privatePropertyWithoutBackingField.kt b/backend.native/tests/external/codegen/blackbox/properties/privatePropertyWithoutBackingField.kt new file mode 100644 index 00000000000..e03074deaa0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/privatePropertyWithoutBackingField.kt @@ -0,0 +1,17 @@ +class Test { + private var i : Int + get() = 1 + set(i) {} + + fun foo() { + fun f() { + i = 2 + } + f() + } +} + +fun box(): String { + Test().foo() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/properties/protectedJavaFieldInInline.kt b/backend.native/tests/external/codegen/blackbox/properties/protectedJavaFieldInInline.kt new file mode 100644 index 00000000000..deec2e94003 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/protectedJavaFieldInInline.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: JavaClass.java + +public class JavaClass { + + protected String FIELD = "OK"; + +} + +// FILE: Kotlin.kt + +package test + +import JavaClass + +class B : JavaClass() { + inline fun bar() = FIELD +} + +fun box() = B().bar() diff --git a/backend.native/tests/external/codegen/blackbox/properties/protectedJavaProperty.kt b/backend.native/tests/external/codegen/blackbox/properties/protectedJavaProperty.kt new file mode 100644 index 00000000000..356a55f75d0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/protectedJavaProperty.kt @@ -0,0 +1,40 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: JavaBaseClass.java + +public class JavaBaseClass { + + private String field = "fail"; + + protected String getFoo() { + return field; + } + + protected void setFoo(String foo) { + field = foo; + } +} + +// FILE: kotlin.kt + +package z + +import JavaBaseClass + +object KotlinExtender : JavaBaseClass() { + @JvmStatic fun test(): String { + return runSlowly { + foo = "OK" + foo + } + } +} +fun runSlowly(f: () -> String): String { + return f() +} + +fun box(): String { + return KotlinExtender.test() +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/protectedJavaPropertyInCompanion.kt b/backend.native/tests/external/codegen/blackbox/properties/protectedJavaPropertyInCompanion.kt new file mode 100644 index 00000000000..242ce0f8006 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/protectedJavaPropertyInCompanion.kt @@ -0,0 +1,48 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: JavaBaseClass.java + +public class JavaBaseClass { + + private String field = "fail"; + + protected String getFoo() { + return field; + } + + protected void setFoo(String foo) { + field = foo; + } +} + +// FILE: kotlin.kt + +package z + +import JavaBaseClass + +class A { + @JvmField var foo = "fail" + + companion object : JavaBaseClass() { + @JvmStatic fun test(): String { + return runSlowly { + foo = "OK" + foo + } + } + } +} +fun runSlowly(f: () -> String): String { + return f() +} + +fun box(): String { + val a = A() + a.foo = "Kotlin" + if (a.foo != "Kotlin") return "fail" + + return A.test() +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/substituteJavaSuperField.kt b/backend.native/tests/external/codegen/blackbox/properties/substituteJavaSuperField.kt new file mode 100644 index 00000000000..03c3ff2b6cf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/substituteJavaSuperField.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: Test.java + +public abstract class Test { + protected final F value = null; +} + +// FILE: test.kt +// See KT-5445: Bad access to protected data in getfield + +class A : Test() { + fun foo(): String? = value + fun bar(): String? = this.value +} + +fun box(): String { + if (A().foo() != null) return "Fail 1" + if (A().bar() != null) return "Fail 2" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/properties/twoAnnotatedExtensionPropertiesWithoutBackingFields.kt b/backend.native/tests/external/codegen/blackbox/properties/twoAnnotatedExtensionPropertiesWithoutBackingFields.kt new file mode 100644 index 00000000000..678b82c784e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/twoAnnotatedExtensionPropertiesWithoutBackingFields.kt @@ -0,0 +1,9 @@ +annotation class Anno + +@Anno val Int.foo: Int + get() = this + +@Anno val String.foo: Int + get() = 42 + +fun box() = if (42.foo == 42 && "OK".foo == 42) "OK" else "Fail" diff --git a/backend.native/tests/external/codegen/blackbox/properties/typeInferredFromGetter.kt b/backend.native/tests/external/codegen/blackbox/properties/typeInferredFromGetter.kt new file mode 100644 index 00000000000..f4f042888b1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/properties/typeInferredFromGetter.kt @@ -0,0 +1,7 @@ +val x get() = "O" + +class A { + val y get() = "K" +} + +fun box() = x + A().y diff --git a/backend.native/tests/external/codegen/blackbox/publishedApi/noMangling.kt b/backend.native/tests/external/codegen/blackbox/publishedApi/noMangling.kt new file mode 100644 index 00000000000..deeb37b9064 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/publishedApi/noMangling.kt @@ -0,0 +1,15 @@ +// IGNORE_BACKEND: JS, NATIVE +//WITH_REFLECT +class A { + @PublishedApi + internal fun published() = "OK" + + inline fun test() = published() + +} + +fun box() : String { + val clazz = A::class.java + if (clazz.getDeclaredMethod("published") == null) return "fail" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/publishedApi/simple.kt b/backend.native/tests/external/codegen/blackbox/publishedApi/simple.kt new file mode 100644 index 00000000000..4ad78979fd4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/publishedApi/simple.kt @@ -0,0 +1,16 @@ +// MODULE: lib +// FILE: lib.kt +class A { + + @PublishedApi + internal fun published() = "OK" + + inline fun test() = published() + +} + +// MODULE: main(lib) +// FILE: main.kt +fun box(): String { + return A().test() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/publishedApi/topLevel.kt b/backend.native/tests/external/codegen/blackbox/publishedApi/topLevel.kt new file mode 100644 index 00000000000..e2a33400e7d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/publishedApi/topLevel.kt @@ -0,0 +1,10 @@ +// MODULE: lib +// FILE: lib.kt +@PublishedApi +internal fun published() = "OK" + +inline fun test() = published() + +// MODULE: main(lib) +// FILE: main.kt +fun box() = test() \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/contains/inComparableRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/contains/inComparableRange.kt new file mode 100644 index 00000000000..9f3c461c773 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/contains/inComparableRange.kt @@ -0,0 +1,50 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class ComparablePair>(val first: T, val second: T) : Comparable> { + override fun compareTo(other: ComparablePair): Int { + val result = first.compareTo(other.first) + return if (result != 0) result else second.compareTo(other.second) + } +} + +fun > genericRangeTo(start: T, endInclusive: T) = start..endInclusive +operator fun Double.rangeTo(other: Double) = genericRangeTo(this, other) +// some weird inverted range +operator fun Float.rangeTo(other: Float) = object : ClosedFloatingPointRange { + override val endInclusive: Float = this@rangeTo + override val start: Float = other + override fun lessThanOrEquals(a: Float, b: Float) = a >= b +} + +fun check(x: Double, left: Double, right: Double): Boolean { + val result = x in left..right + val range = left..right + assert(result == x in range) { "Failed: unoptimized === unoptimized for custom double $range" } + return result +} + +fun check(x: Float, left: Float, right: Float): Boolean { + val result = x in left..right + val range = left..right + assert(result == x in range) { "Failed: unoptimized === unoptimized for standard float $range" } + return result +} + +fun box(): String { + assert("a" !in "b".."c") + assert("b" in "a".."d") + + assert(ComparablePair(2, 2) !in ComparablePair(1, 10)..ComparablePair(2, 1)) + assert(ComparablePair(2, 2) in ComparablePair(2, 0)..ComparablePair(2, 10)) + + assert(!check(-0.0, 0.0, 0.0)) + assert(check(Double.NaN, Double.NaN, Double.NaN)) + + assert(check(-0.0f, 0.0f, 0.0f)) + assert(!check(Float.NaN, Float.NaN, Float.NaN)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/contains/inExtensionRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/contains/inExtensionRange.kt new file mode 100644 index 00000000000..b216292520a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/contains/inExtensionRange.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +operator fun Int.rangeTo(right: String): ClosedRange = this..this + 1 +operator fun Long.rangeTo(right: Double): ClosedRange = this..right.toLong() + 1 +operator fun String.rangeTo(right: Int): ClosedRange = this..this + +fun box(): String { + assert(0 !in 1.."a") + assert(1 in 1.."a") + + assert(0L !in 1L..2.0) + assert(2L in 1L..3.0) + + assert("a" !in "b"..1) + assert("a" in "a"..1) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/contains/inIntRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/contains/inIntRange.kt new file mode 100644 index 00000000000..cf82a3033c8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/contains/inIntRange.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String { + for (x in 1..10) { + assert(x in 1..10) + assert(x + 10 !in 1..10) + } + + var x = 0 + assert(0 !in 1..2) + + assert(++x in 1..1) + assert(++x !in 1..1) + + assert(sideEffect(x) in 2..3) + return "OK" +} + + +var invocationCounter = 0 +fun sideEffect(x: Int): Int { + ++invocationCounter + assert(invocationCounter == 1) + return x +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/contains/inOptimizableDoubleRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/contains/inOptimizableDoubleRange.kt new file mode 100644 index 00000000000..049667b8d18 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/contains/inOptimizableDoubleRange.kt @@ -0,0 +1,39 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun check(x: Double, left: Double, right: Double): Boolean { + val result = x in left..right + val manual = x >= left && x <= right + val range = left..right + assert(result == manual) { "Failed: optimized === manual for $range" } + assert(result == checkUnoptimized(x, range)) { "Failed: optimized === unoptimized for $range" } + return result +} + +fun checkUnoptimized(x: Double, range: ClosedRange): Boolean { + return x in range +} + +fun box(): String { + assert(check(1.0, 0.0, 2.0)) + assert(!check(1.0, -1.0, 0.0)) + + assert(check(Double.MIN_VALUE, 0.0, 1.0)) + assert(check(Double.MAX_VALUE, Double.MAX_VALUE - Double.MIN_VALUE, Double.MAX_VALUE)) + assert(!check(Double.NaN, Double.NaN, Double.NaN)) + assert(!check(0.0, Double.NaN, Double.NaN)) + + assert(check(-0.0, -0.0, +0.0)) + assert(check(-0.0, -0.0, -0.0)) + assert(check(-0.0, +0.0, +0.0)) + assert(check(+0.0, -0.0, -0.0)) + assert(check(+0.0, +0.0, +0.0)) + assert(check(+0.0, -0.0, +0.0)) + + var value = 0.0 + assert(++value in 1.0..1.0) + assert(++value !in 1.0..1.0) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/contains/inOptimizableFloatRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/contains/inOptimizableFloatRange.kt new file mode 100644 index 00000000000..c58a00c6b20 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/contains/inOptimizableFloatRange.kt @@ -0,0 +1,39 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun check(x: Float, left: Float, right: Float): Boolean { + val result = x in left..right + val manual = x >= left && x <= right + val range = left..right + assert(result == manual) { "Failed: optimized === manual for $range" } + assert(result == checkUnoptimized(x, range)) { "Failed: optimized === unoptimized for $range" } + return result +} + +fun checkUnoptimized(x: Float, range: ClosedRange): Boolean { + return x in range +} + +fun box(): String { + assert(check(1.0f, 0.0f, 2.0f)) + assert(!check(1.0f, -1.0f, 0.0f)) + + assert(check(Float.MIN_VALUE, 0.0f, 1.0f)) + assert(check(Float.MAX_VALUE, Float.MAX_VALUE - Float.MIN_VALUE, Float.MAX_VALUE)) + assert(!check(Float.NaN, Float.NaN, Float.NaN)) + assert(!check(0.0f, Float.NaN, Float.NaN)) + + assert(check(-0.0f, -0.0f, +0.0f)) + assert(check(-0.0f, -0.0f, -0.0f)) + assert(check(-0.0f, +0.0f, +0.0f)) + assert(check(+0.0f, -0.0f, -0.0f)) + assert(check(+0.0f, +0.0f, +0.0f)) + assert(check(+0.0f, -0.0f, +0.0f)) + + var value = 0.0f + assert(++value in 1.0f..1.0f) + assert(++value !in 1.0f..1.0f) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/contains/inOptimizableIntRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/contains/inOptimizableIntRange.kt new file mode 100644 index 00000000000..969571dcafb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/contains/inOptimizableIntRange.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun check(x: Int, left: Int, right: Int): Boolean { + val result = x in left..right + val manual = x >= left && x <= right + val range = left..right + assert(result == manual) { "Failed: optimized === manual for $range" } + assert(result == checkUnoptimized(x, range)) { "Failed: optimized === unoptimized for $range" } + return result +} + +fun checkUnoptimized(x: Int, range: ClosedRange): Boolean { + return x in range +} + +fun box(): String { + assert(check(1, 0, 2)) + assert(!check(1, -1, 0)) + assert(!check(239, 239, 238)) + assert(check(239, 238, 239)) + + assert(check(Int.MIN_VALUE, Int.MIN_VALUE, Int.MIN_VALUE)) + assert(check(Int.MAX_VALUE, Int.MIN_VALUE, Int.MAX_VALUE)) + + var value = 0 + assert(++value in 1..1) + assert(++value !in 1..1) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/contains/inOptimizableLongRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/contains/inOptimizableLongRange.kt new file mode 100644 index 00000000000..61e9bf4c898 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/contains/inOptimizableLongRange.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun check(x: Long, left: Long, right: Long): Boolean { + val result = x in left..right + val manual = x >= left && x <= right + val range = left..right + assert(result == manual) { "Failed: optimized === manual for $range" } + assert(result == checkUnoptimized(x, range)) { "Failed: optimized === unoptimized for $range" } + return result +} + +fun checkUnoptimized(x: Long, range: ClosedRange): Boolean { + return x in range +} + +fun box(): String { + assert(check(1L, 0L, 2L)) + assert(!check(1L, -1L, 0L)) + assert(!check(239L, 239L, 238L)) + assert(check(239L, 238L, 239L)) + + assert(check(Long.MIN_VALUE, Long.MIN_VALUE, Long.MIN_VALUE)) + assert(check(Long.MAX_VALUE, Long.MIN_VALUE, Long.MAX_VALUE)) + + var value = 0L + assert(++value in 1L..1L) + assert(++value !in 1L..1L) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/contains/inRangeWithCustomContains.kt b/backend.native/tests/external/codegen/blackbox/ranges/contains/inRangeWithCustomContains.kt new file mode 100644 index 00000000000..0071b2d423a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/contains/inRangeWithCustomContains.kt @@ -0,0 +1,27 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class Value(val x: Int) : Comparable { + override fun compareTo(other: Value): Int { + throw AssertionError("Should not be called") + } +} + +class ValueRange(override val start: Value, + override val endInclusive: Value) : ClosedRange { + + override fun contains(value: Value): Boolean { + return value.x == 42 + } +} + +operator fun Value.rangeTo(other: Value): ClosedRange = ValueRange(this, other) + +fun box(): String { + assert(Value(42) in Value(1)..Value(2)) + assert(Value(41) !in Value(40)..Value(42)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/contains/inRangeWithImplicitReceiver.kt b/backend.native/tests/external/codegen/blackbox/ranges/contains/inRangeWithImplicitReceiver.kt new file mode 100644 index 00000000000..d5bb738d866 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/contains/inRangeWithImplicitReceiver.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun Long.inLongs(l: Long, r: Long): Boolean { + return this in l..r +} + +fun Double.inDoubles(l: Double, r: Double): Boolean { + return this in l..r +} + +fun box(): String { + assert(2L.inLongs(1L, 3L)) + assert(!2L.inLongs(0L, 1L)) + + assert(2.0.inDoubles(1.0, 3.0)) + assert(!2.0.inDoubles(0.0, 1.0)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/contains/inRangeWithNonmatchingArguments.kt b/backend.native/tests/external/codegen/blackbox/ranges/contains/inRangeWithNonmatchingArguments.kt new file mode 100644 index 00000000000..23219eac00f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/contains/inRangeWithNonmatchingArguments.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String { + assert(Long.MAX_VALUE !in Int.MIN_VALUE..Int.MAX_VALUE) + assert(Int.MAX_VALUE in Long.MIN_VALUE..Long.MAX_VALUE) + assert(Double.MAX_VALUE !in Float.MIN_VALUE..Float.MAX_VALUE) + assert(Float.MIN_VALUE in 0..1) + assert(2.0 !in 1..0) + assert(1.0f in 0L..2L) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/contains/inRangeWithSmartCast.kt b/backend.native/tests/external/codegen/blackbox/ranges/contains/inRangeWithSmartCast.kt new file mode 100644 index 00000000000..1c314ffa31f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/contains/inRangeWithSmartCast.kt @@ -0,0 +1,29 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun check(x: Any?): Boolean { + if (x is Int) { + return x in 239..240 + } + + throw java.lang.AssertionError() +} + +fun check(x: Any?, l: Any?, r: Any?): Boolean { + if (x is Int && l is Int && r is Int) { + return x in l..r + } + + throw java.lang.AssertionError() +} + + +fun box(): String { + assert(check(239)) + assert(check(239, 239, 240)) + assert(!check(238)) + assert(!check(238, 239, 240)) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/contains/rangeContainsString.kt b/backend.native/tests/external/codegen/blackbox/ranges/contains/rangeContainsString.kt new file mode 100644 index 00000000000..9e2c9269f96 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/contains/rangeContainsString.kt @@ -0,0 +1,5 @@ +operator fun IntRange.contains(s: String): Boolean = true + +fun box(): String { + return if ("s" in 0..1) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/emptyDownto.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/emptyDownto.kt new file mode 100644 index 00000000000..41f9e9357a0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/emptyDownto.kt @@ -0,0 +1,57 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = 5 downTo 10 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for 5 downTo 10: $list1" + } + + val list2 = ArrayList() + val range2 = 5.toByte() downTo 10.toByte() + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for 5.toByte() downTo 10.toByte(): $list2" + } + + val list3 = ArrayList() + val range3 = 5.toShort() downTo 10.toShort() + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for 5.toShort() downTo 10.toShort(): $list3" + } + + val list4 = ArrayList() + val range4 = 5.toLong() downTo 10.toLong() + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for 5.toLong() downTo 10.toLong(): $list4" + } + + val list5 = ArrayList() + val range5 = 'a' downTo 'z' + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for 'a' downTo 'z': $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/emptyRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/emptyRange.kt new file mode 100644 index 00000000000..01f8c158cac --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/emptyRange.kt @@ -0,0 +1,57 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = 10..5 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for 10..5: $list1" + } + + val list2 = ArrayList() + val range2 = 10.toByte()..(-5).toByte() + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for 10.toByte()..(-5).toByte(): $list2" + } + + val list3 = ArrayList() + val range3 = 10.toShort()..(-5).toShort() + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for 10.toShort()..(-5).toShort(): $list3" + } + + val list4 = ArrayList() + val range4 = 10.toLong()..-5.toLong() + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for 10.toLong()..-5.toLong(): $list4" + } + + val list5 = ArrayList() + val range5 = 'z'..'a' + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for 'z'..'a': $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/inexactDownToMinValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/inexactDownToMinValue.kt new file mode 100644 index 00000000000..e0fd14c2983 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/inexactDownToMinValue.kt @@ -0,0 +1,71 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = (MinI + 5) downTo MinI step 3 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(MinI + 5, MinI + 2)) { + return "Wrong elements for (MinI + 5) downTo MinI step 3: $list1" + } + + val list2 = ArrayList() + val range2 = (MinB + 5).toByte() downTo MinB step 3 + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf((MinB + 5).toInt(), (MinB + 2).toInt())) { + return "Wrong elements for (MinB + 5).toByte() downTo MinB step 3: $list2" + } + + val list3 = ArrayList() + val range3 = (MinS + 5).toShort() downTo MinS step 3 + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf((MinS + 5).toInt(), (MinS + 2).toInt())) { + return "Wrong elements for (MinS + 5).toShort() downTo MinS step 3: $list3" + } + + val list4 = ArrayList() + val range4 = (MinL + 5).toLong() downTo MinL step 3 + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf((MinL + 5).toLong(), (MinL + 2).toLong())) { + return "Wrong elements for (MinL + 5).toLong() downTo MinL step 3: $list4" + } + + val list5 = ArrayList() + val range5 = (MinC + 5) downTo MinC step 3 + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf((MinC + 5), (MinC + 2))) { + return "Wrong elements for (MinC + 5) downTo MinC step 3: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/inexactSteppedDownTo.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/inexactSteppedDownTo.kt new file mode 100644 index 00000000000..5b7871e8f3f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/inexactSteppedDownTo.kt @@ -0,0 +1,57 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = 8 downTo 3 step 2 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(8, 6, 4)) { + return "Wrong elements for 8 downTo 3 step 2: $list1" + } + + val list2 = ArrayList() + val range2 = 8.toByte() downTo 3.toByte() step 2 + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(8, 6, 4)) { + return "Wrong elements for 8.toByte() downTo 3.toByte() step 2: $list2" + } + + val list3 = ArrayList() + val range3 = 8.toShort() downTo 3.toShort() step 2 + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(8, 6, 4)) { + return "Wrong elements for 8.toShort() downTo 3.toShort() step 2: $list3" + } + + val list4 = ArrayList() + val range4 = 8.toLong() downTo 3.toLong() step 2.toLong() + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(8, 6, 4)) { + return "Wrong elements for 8.toLong() downTo 3.toLong() step 2.toLong(): $list4" + } + + val list5 = ArrayList() + val range5 = 'd' downTo 'a' step 2 + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('d', 'b')) { + return "Wrong elements for 'd' downTo 'a' step 2: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/inexactSteppedRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/inexactSteppedRange.kt new file mode 100644 index 00000000000..f746a9fd09b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/inexactSteppedRange.kt @@ -0,0 +1,57 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = 3..8 step 2 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(3, 5, 7)) { + return "Wrong elements for 3..8 step 2: $list1" + } + + val list2 = ArrayList() + val range2 = 3.toByte()..8.toByte() step 2 + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(3, 5, 7)) { + return "Wrong elements for 3.toByte()..8.toByte() step 2: $list2" + } + + val list3 = ArrayList() + val range3 = 3.toShort()..8.toShort() step 2 + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(3, 5, 7)) { + return "Wrong elements for 3.toShort()..8.toShort() step 2: $list3" + } + + val list4 = ArrayList() + val range4 = 3.toLong()..8.toLong() step 2.toLong() + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(3, 5, 7)) { + return "Wrong elements for 3.toLong()..8.toLong() step 2.toLong(): $list4" + } + + val list5 = ArrayList() + val range5 = 'a'..'d' step 2 + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('a', 'c')) { + return "Wrong elements for 'a'..'d' step 2: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/inexactToMaxValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/inexactToMaxValue.kt new file mode 100644 index 00000000000..74712e4df72 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/inexactToMaxValue.kt @@ -0,0 +1,71 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = (MaxI - 5)..MaxI step 3 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(MaxI - 5, MaxI - 2)) { + return "Wrong elements for (MaxI - 5)..MaxI step 3: $list1" + } + + val list2 = ArrayList() + val range2 = (MaxB - 5).toByte()..MaxB step 3 + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf((MaxB - 5).toInt(), (MaxB - 2).toInt())) { + return "Wrong elements for (MaxB - 5).toByte()..MaxB step 3: $list2" + } + + val list3 = ArrayList() + val range3 = (MaxS - 5).toShort()..MaxS step 3 + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf((MaxS - 5).toInt(), (MaxS - 2).toInt())) { + return "Wrong elements for (MaxS - 5).toShort()..MaxS step 3: $list3" + } + + val list4 = ArrayList() + val range4 = (MaxL - 5).toLong()..MaxL step 3 + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf((MaxL - 5).toLong(), (MaxL - 2).toLong())) { + return "Wrong elements for (MaxL - 5).toLong()..MaxL step 3: $list4" + } + + val list5 = ArrayList() + val range5 = (MaxC - 5)..MaxC step 3 + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf((MaxC - 5), (MaxC - 2))) { + return "Wrong elements for (MaxC - 5)..MaxC step 3: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/maxValueMinusTwoToMaxValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/maxValueMinusTwoToMaxValue.kt new file mode 100644 index 00000000000..0cc89f13224 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/maxValueMinusTwoToMaxValue.kt @@ -0,0 +1,71 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = (MaxI - 2)..MaxI + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(MaxI - 2, MaxI - 1, MaxI)) { + return "Wrong elements for (MaxI - 2)..MaxI: $list1" + } + + val list2 = ArrayList() + val range2 = (MaxB - 2).toByte()..MaxB + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf((MaxB - 2).toInt(), (MaxB - 1).toInt(), MaxB.toInt())) { + return "Wrong elements for (MaxB - 2).toByte()..MaxB: $list2" + } + + val list3 = ArrayList() + val range3 = (MaxS - 2).toShort()..MaxS + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf((MaxS - 2).toInt(), (MaxS - 1).toInt(), MaxS.toInt())) { + return "Wrong elements for (MaxS - 2).toShort()..MaxS: $list3" + } + + val list4 = ArrayList() + val range4 = (MaxL - 2).toLong()..MaxL + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf((MaxL - 2).toLong(), (MaxL - 1).toLong(), MaxL)) { + return "Wrong elements for (MaxL - 2).toLong()..MaxL: $list4" + } + + val list5 = ArrayList() + val range5 = (MaxC - 2)..MaxC + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf((MaxC - 2), (MaxC - 1), MaxC)) { + return "Wrong elements for (MaxC - 2)..MaxC: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/maxValueToMaxValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/maxValueToMaxValue.kt new file mode 100644 index 00000000000..c60b83b3d93 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/maxValueToMaxValue.kt @@ -0,0 +1,71 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = MaxI..MaxI + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(MaxI)) { + return "Wrong elements for MaxI..MaxI: $list1" + } + + val list2 = ArrayList() + val range2 = MaxB..MaxB + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(MaxB.toInt())) { + return "Wrong elements for MaxB..MaxB: $list2" + } + + val list3 = ArrayList() + val range3 = MaxS..MaxS + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(MaxS.toInt())) { + return "Wrong elements for MaxS..MaxS: $list3" + } + + val list4 = ArrayList() + val range4 = MaxL..MaxL + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(MaxL)) { + return "Wrong elements for MaxL..MaxL: $list4" + } + + val list5 = ArrayList() + val range5 = MaxC..MaxC + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf(MaxC)) { + return "Wrong elements for MaxC..MaxC: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/maxValueToMinValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/maxValueToMinValue.kt new file mode 100644 index 00000000000..d7e7f98a24a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/maxValueToMinValue.kt @@ -0,0 +1,71 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = MaxI..MinI + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for MaxI..MinI: $list1" + } + + val list2 = ArrayList() + val range2 = MaxB..MinB + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for MaxB..MinB: $list2" + } + + val list3 = ArrayList() + val range3 = MaxS..MinS + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for MaxS..MinS: $list3" + } + + val list4 = ArrayList() + val range4 = MaxL..MinL + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for MaxL..MinL: $list4" + } + + val list5 = ArrayList() + val range5 = MaxC..MinC + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for MaxC..MinC: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/oneElementDownTo.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/oneElementDownTo.kt new file mode 100644 index 00000000000..302fd2bc7c3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/oneElementDownTo.kt @@ -0,0 +1,57 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = 5 downTo 5 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(5)) { + return "Wrong elements for 5 downTo 5: $list1" + } + + val list2 = ArrayList() + val range2 = 5.toByte() downTo 5.toByte() + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(5)) { + return "Wrong elements for 5.toByte() downTo 5.toByte(): $list2" + } + + val list3 = ArrayList() + val range3 = 5.toShort() downTo 5.toShort() + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(5)) { + return "Wrong elements for 5.toShort() downTo 5.toShort(): $list3" + } + + val list4 = ArrayList() + val range4 = 5.toLong() downTo 5.toLong() + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(5.toLong())) { + return "Wrong elements for 5.toLong() downTo 5.toLong(): $list4" + } + + val list5 = ArrayList() + val range5 = 'k' downTo 'k' + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('k')) { + return "Wrong elements for 'k' downTo 'k': $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/oneElementRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/oneElementRange.kt new file mode 100644 index 00000000000..065acfd5333 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/oneElementRange.kt @@ -0,0 +1,57 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = 5..5 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(5)) { + return "Wrong elements for 5..5: $list1" + } + + val list2 = ArrayList() + val range2 = 5.toByte()..5.toByte() + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(5)) { + return "Wrong elements for 5.toByte()..5.toByte(): $list2" + } + + val list3 = ArrayList() + val range3 = 5.toShort()..5.toShort() + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(5)) { + return "Wrong elements for 5.toShort()..5.toShort(): $list3" + } + + val list4 = ArrayList() + val range4 = 5.toLong()..5.toLong() + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(5.toLong())) { + return "Wrong elements for 5.toLong()..5.toLong(): $list4" + } + + val list5 = ArrayList() + val range5 = 'k'..'k' + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('k')) { + return "Wrong elements for 'k'..'k': $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/openRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/openRange.kt new file mode 100644 index 00000000000..c9a06cc49d6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/openRange.kt @@ -0,0 +1,57 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = 1 until 5 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(1, 2, 3, 4)) { + return "Wrong elements for 1 until 5: $list1" + } + + val list2 = ArrayList() + val range2 = 1.toByte() until 5.toByte() + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(1, 2, 3, 4)) { + return "Wrong elements for 1.toByte() until 5.toByte(): $list2" + } + + val list3 = ArrayList() + val range3 = 1.toShort() until 5.toShort() + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(1, 2, 3, 4)) { + return "Wrong elements for 1.toShort() until 5.toShort(): $list3" + } + + val list4 = ArrayList() + val range4 = 1.toLong() until 5.toLong() + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(1, 2, 3, 4)) { + return "Wrong elements for 1.toLong() until 5.toLong(): $list4" + } + + val list5 = ArrayList() + val range5 = 'a' until 'd' + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('a', 'b', 'c')) { + return "Wrong elements for 'a' until 'd': $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/progressionDownToMinValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/progressionDownToMinValue.kt new file mode 100644 index 00000000000..20ef6402572 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/progressionDownToMinValue.kt @@ -0,0 +1,71 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = (MinI + 2) downTo MinI step 1 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(MinI + 2, MinI + 1, MinI)) { + return "Wrong elements for (MinI + 2) downTo MinI step 1: $list1" + } + + val list2 = ArrayList() + val range2 = (MinB + 2).toByte() downTo MinB step 1 + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf((MinB + 2).toInt(), (MinB + 1).toInt(), MinB.toInt())) { + return "Wrong elements for (MinB + 2).toByte() downTo MinB step 1: $list2" + } + + val list3 = ArrayList() + val range3 = (MinS + 2).toShort() downTo MinS step 1 + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf((MinS + 2).toInt(), (MinS + 1).toInt(), MinS.toInt())) { + return "Wrong elements for (MinS + 2).toShort() downTo MinS step 1: $list3" + } + + val list4 = ArrayList() + val range4 = (MinL + 2).toLong() downTo MinL step 1 + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf((MinL + 2).toLong(), (MinL + 1).toLong(), MinL)) { + return "Wrong elements for (MinL + 2).toLong() downTo MinL step 1: $list4" + } + + val list5 = ArrayList() + val range5 = (MinC + 2) downTo MinC step 1 + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf((MinC + 2), (MinC + 1), MinC)) { + return "Wrong elements for (MinC + 2) downTo MinC step 1: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/progressionMaxValueMinusTwoToMaxValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/progressionMaxValueMinusTwoToMaxValue.kt new file mode 100644 index 00000000000..cd579903938 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/progressionMaxValueMinusTwoToMaxValue.kt @@ -0,0 +1,71 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = (MaxI - 2)..MaxI step 2 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(MaxI - 2, MaxI)) { + return "Wrong elements for (MaxI - 2)..MaxI step 2: $list1" + } + + val list2 = ArrayList() + val range2 = (MaxB - 2).toByte()..MaxB step 2 + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf((MaxB - 2).toInt(), MaxB.toInt())) { + return "Wrong elements for (MaxB - 2).toByte()..MaxB step 2: $list2" + } + + val list3 = ArrayList() + val range3 = (MaxS - 2).toShort()..MaxS step 2 + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf((MaxS - 2).toInt(), MaxS.toInt())) { + return "Wrong elements for (MaxS - 2).toShort()..MaxS step 2: $list3" + } + + val list4 = ArrayList() + val range4 = (MaxL - 2).toLong()..MaxL step 2 + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf((MaxL - 2).toLong(), MaxL)) { + return "Wrong elements for (MaxL - 2).toLong()..MaxL step 2: $list4" + } + + val list5 = ArrayList() + val range5 = (MaxC - 2)..MaxC step 2 + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf((MaxC - 2), MaxC)) { + return "Wrong elements for (MaxC - 2)..MaxC step 2: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/progressionMaxValueToMaxValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/progressionMaxValueToMaxValue.kt new file mode 100644 index 00000000000..691b83d6f48 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/progressionMaxValueToMaxValue.kt @@ -0,0 +1,71 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = MaxI..MaxI step 1 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(MaxI)) { + return "Wrong elements for MaxI..MaxI step 1: $list1" + } + + val list2 = ArrayList() + val range2 = MaxB..MaxB step 1 + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(MaxB.toInt())) { + return "Wrong elements for MaxB..MaxB step 1: $list2" + } + + val list3 = ArrayList() + val range3 = MaxS..MaxS step 1 + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(MaxS.toInt())) { + return "Wrong elements for MaxS..MaxS step 1: $list3" + } + + val list4 = ArrayList() + val range4 = MaxL..MaxL step 1 + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(MaxL)) { + return "Wrong elements for MaxL..MaxL step 1: $list4" + } + + val list5 = ArrayList() + val range5 = MaxC..MaxC step 1 + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf(MaxC)) { + return "Wrong elements for MaxC..MaxC step 1: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/progressionMaxValueToMinValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/progressionMaxValueToMinValue.kt new file mode 100644 index 00000000000..1083ef991a2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/progressionMaxValueToMinValue.kt @@ -0,0 +1,71 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = MaxI..MinI step 1 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for MaxI..MinI step 1: $list1" + } + + val list2 = ArrayList() + val range2 = MaxB..MinB step 1 + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for MaxB..MinB step 1: $list2" + } + + val list3 = ArrayList() + val range3 = MaxS..MinS step 1 + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for MaxS..MinS step 1: $list3" + } + + val list4 = ArrayList() + val range4 = MaxL..MinL step 1 + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for MaxL..MinL step 1: $list4" + } + + val list5 = ArrayList() + val range5 = MaxC..MinC step 1 + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for MaxC..MinC step 1: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/progressionMinValueToMinValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/progressionMinValueToMinValue.kt new file mode 100644 index 00000000000..c85495c3743 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/progressionMinValueToMinValue.kt @@ -0,0 +1,71 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = MinI..MinI step 1 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(MinI)) { + return "Wrong elements for MinI..MinI step 1: $list1" + } + + val list2 = ArrayList() + val range2 = MinB..MinB step 1 + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(MinB.toInt())) { + return "Wrong elements for MinB..MinB step 1: $list2" + } + + val list3 = ArrayList() + val range3 = MinS..MinS step 1 + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(MinS.toInt())) { + return "Wrong elements for MinS..MinS step 1: $list3" + } + + val list4 = ArrayList() + val range4 = MinL..MinL step 1 + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(MinL)) { + return "Wrong elements for MinL..MinL step 1: $list4" + } + + val list5 = ArrayList() + val range5 = MinC..MinC step 1 + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf(MinC)) { + return "Wrong elements for MinC..MinC step 1: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedBackSequence.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedBackSequence.kt new file mode 100644 index 00000000000..3542aa875b8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedBackSequence.kt @@ -0,0 +1,57 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = (5 downTo 3).reversed() + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(3, 4, 5)) { + return "Wrong elements for (5 downTo 3).reversed(): $list1" + } + + val list2 = ArrayList() + val range2 = (5.toByte() downTo 3.toByte()).reversed() + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(3, 4, 5)) { + return "Wrong elements for (5.toByte() downTo 3.toByte()).reversed(): $list2" + } + + val list3 = ArrayList() + val range3 = (5.toShort() downTo 3.toShort()).reversed() + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(3, 4, 5)) { + return "Wrong elements for (5.toShort() downTo 3.toShort()).reversed(): $list3" + } + + val list4 = ArrayList() + val range4 = (5.toLong() downTo 3.toLong()).reversed() + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(3, 4, 5)) { + return "Wrong elements for (5.toLong() downTo 3.toLong()).reversed(): $list4" + } + + val list5 = ArrayList() + val range5 = ('c' downTo 'a').reversed() + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('a', 'b', 'c')) { + return "Wrong elements for ('c' downTo 'a').reversed(): $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedEmptyBackSequence.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedEmptyBackSequence.kt new file mode 100644 index 00000000000..dc259b75860 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedEmptyBackSequence.kt @@ -0,0 +1,57 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = (3 downTo 5).reversed() + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for (3 downTo 5).reversed(): $list1" + } + + val list2 = ArrayList() + val range2 = (3.toByte() downTo 5.toByte()).reversed() + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for (3.toByte() downTo 5.toByte()).reversed(): $list2" + } + + val list3 = ArrayList() + val range3 = (3.toShort() downTo 5.toShort()).reversed() + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for (3.toShort() downTo 5.toShort()).reversed(): $list3" + } + + val list4 = ArrayList() + val range4 = (3.toLong() downTo 5.toLong()).reversed() + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for (3.toLong() downTo 5.toLong()).reversed(): $list4" + } + + val list5 = ArrayList() + val range5 = ('a' downTo 'c').reversed() + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for ('a' downTo 'c').reversed(): $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedEmptyRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedEmptyRange.kt new file mode 100644 index 00000000000..436528a5cd9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedEmptyRange.kt @@ -0,0 +1,57 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = (5..3).reversed() + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for (5..3).reversed(): $list1" + } + + val list2 = ArrayList() + val range2 = (5.toByte()..3.toByte()).reversed() + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for (5.toByte()..3.toByte()).reversed(): $list2" + } + + val list3 = ArrayList() + val range3 = (5.toShort()..3.toShort()).reversed() + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for (5.toShort()..3.toShort()).reversed(): $list3" + } + + val list4 = ArrayList() + val range4 = (5.toLong()..3.toLong()).reversed() + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for (5.toLong()..3.toLong()).reversed(): $list4" + } + + val list5 = ArrayList() + val range5 = ('c'..'a').reversed() + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for ('c'..'a').reversed(): $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedInexactSteppedDownTo.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedInexactSteppedDownTo.kt new file mode 100644 index 00000000000..03d7e797926 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedInexactSteppedDownTo.kt @@ -0,0 +1,57 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = (8 downTo 3 step 2).reversed() + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(4, 6, 8)) { + return "Wrong elements for (8 downTo 3 step 2).reversed(): $list1" + } + + val list2 = ArrayList() + val range2 = (8.toByte() downTo 3.toByte() step 2).reversed() + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(4, 6, 8)) { + return "Wrong elements for (8.toByte() downTo 3.toByte() step 2).reversed(): $list2" + } + + val list3 = ArrayList() + val range3 = (8.toShort() downTo 3.toShort() step 2).reversed() + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(4, 6, 8)) { + return "Wrong elements for (8.toShort() downTo 3.toShort() step 2).reversed(): $list3" + } + + val list4 = ArrayList() + val range4 = (8.toLong() downTo 3.toLong() step 2.toLong()).reversed() + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(4, 6, 8)) { + return "Wrong elements for (8.toLong() downTo 3.toLong() step 2.toLong()).reversed(): $list4" + } + + val list5 = ArrayList() + val range5 = ('d' downTo 'a' step 2).reversed() + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('b', 'd')) { + return "Wrong elements for ('d' downTo 'a' step 2).reversed(): $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedRange.kt new file mode 100644 index 00000000000..098c28bf0aa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedRange.kt @@ -0,0 +1,47 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = (3..5).reversed() + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(5, 4, 3)) { + return "Wrong elements for (3..5).reversed(): $list1" + } + + val list2 = ArrayList() + val range2 = (3.toShort()..5.toShort()).reversed() + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(5, 4, 3)) { + return "Wrong elements for (3.toShort()..5.toShort()).reversed(): $list2" + } + + val list3 = ArrayList() + val range3 = (3.toLong()..5.toLong()).reversed() + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(5, 4, 3)) { + return "Wrong elements for (3.toLong()..5.toLong()).reversed(): $list3" + } + + val list4 = ArrayList() + val range4 = ('a'..'c').reversed() + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf('c', 'b', 'a')) { + return "Wrong elements for ('a'..'c').reversed(): $list4" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedSimpleSteppedRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedSimpleSteppedRange.kt new file mode 100644 index 00000000000..43771a5928e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/reversedSimpleSteppedRange.kt @@ -0,0 +1,57 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = (3..9 step 2).reversed() + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(9, 7, 5, 3)) { + return "Wrong elements for (3..9 step 2).reversed(): $list1" + } + + val list2 = ArrayList() + val range2 = (3.toByte()..9.toByte() step 2).reversed() + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(9, 7, 5, 3)) { + return "Wrong elements for (3.toByte()..9.toByte() step 2).reversed(): $list2" + } + + val list3 = ArrayList() + val range3 = (3.toShort()..9.toShort() step 2).reversed() + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(9, 7, 5, 3)) { + return "Wrong elements for (3.toShort()..9.toShort() step 2).reversed(): $list3" + } + + val list4 = ArrayList() + val range4 = (3.toLong()..9.toLong() step 2.toLong()).reversed() + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(9, 7, 5, 3)) { + return "Wrong elements for (3.toLong()..9.toLong() step 2.toLong()).reversed(): $list4" + } + + val list5 = ArrayList() + val range5 = ('c'..'g' step 2).reversed() + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('g', 'e', 'c')) { + return "Wrong elements for ('c'..'g' step 2).reversed(): $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/simpleDownTo.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/simpleDownTo.kt new file mode 100644 index 00000000000..ad8974021a5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/simpleDownTo.kt @@ -0,0 +1,57 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = 9 downTo 3 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(9, 8, 7, 6, 5, 4, 3)) { + return "Wrong elements for 9 downTo 3: $list1" + } + + val list2 = ArrayList() + val range2 = 9.toByte() downTo 3.toByte() + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(9, 8, 7, 6, 5, 4, 3)) { + return "Wrong elements for 9.toByte() downTo 3.toByte(): $list2" + } + + val list3 = ArrayList() + val range3 = 9.toShort() downTo 3.toShort() + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(9, 8, 7, 6, 5, 4, 3)) { + return "Wrong elements for 9.toShort() downTo 3.toShort(): $list3" + } + + val list4 = ArrayList() + val range4 = 9.toLong() downTo 3.toLong() + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(9, 8, 7, 6, 5, 4, 3)) { + return "Wrong elements for 9.toLong() downTo 3.toLong(): $list4" + } + + val list5 = ArrayList() + val range5 = 'g' downTo 'c' + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('g', 'f', 'e', 'd', 'c')) { + return "Wrong elements for 'g' downTo 'c': $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/simpleRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/simpleRange.kt new file mode 100644 index 00000000000..306ab1d6ed0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/simpleRange.kt @@ -0,0 +1,57 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = 3..9 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(3, 4, 5, 6, 7, 8, 9)) { + return "Wrong elements for 3..9: $list1" + } + + val list2 = ArrayList() + val range2 = 3.toByte()..9.toByte() + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(3, 4, 5, 6, 7, 8, 9)) { + return "Wrong elements for 3.toByte()..9.toByte(): $list2" + } + + val list3 = ArrayList() + val range3 = 3.toShort()..9.toShort() + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(3, 4, 5, 6, 7, 8, 9)) { + return "Wrong elements for 3.toShort()..9.toShort(): $list3" + } + + val list4 = ArrayList() + val range4 = 3.toLong()..9.toLong() + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(3, 4, 5, 6, 7, 8, 9)) { + return "Wrong elements for 3.toLong()..9.toLong(): $list4" + } + + val list5 = ArrayList() + val range5 = 'c'..'g' + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('c', 'd', 'e', 'f', 'g')) { + return "Wrong elements for 'c'..'g': $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/simpleRangeWithNonConstantEnds.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/simpleRangeWithNonConstantEnds.kt new file mode 100644 index 00000000000..42a9d01dcf6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/simpleRangeWithNonConstantEnds.kt @@ -0,0 +1,57 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = (1 + 2)..(10 - 1) + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(3, 4, 5, 6, 7, 8, 9)) { + return "Wrong elements for (1 + 2)..(10 - 1): $list1" + } + + val list2 = ArrayList() + val range2 = (1.toByte() + 2.toByte()).toByte()..(10.toByte() - 1.toByte()).toByte() + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(3, 4, 5, 6, 7, 8, 9)) { + return "Wrong elements for (1.toByte() + 2.toByte()).toByte()..(10.toByte() - 1.toByte()).toByte(): $list2" + } + + val list3 = ArrayList() + val range3 = (1.toShort() + 2.toShort()).toShort()..(10.toShort() - 1.toShort()).toShort() + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(3, 4, 5, 6, 7, 8, 9)) { + return "Wrong elements for (1.toShort() + 2.toShort()).toShort()..(10.toShort() - 1.toShort()).toShort(): $list3" + } + + val list4 = ArrayList() + val range4 = (1.toLong() + 2.toLong())..(10.toLong() - 1.toLong()) + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(3, 4, 5, 6, 7, 8, 9)) { + return "Wrong elements for (1.toLong() + 2.toLong())..(10.toLong() - 1.toLong()): $list4" + } + + val list5 = ArrayList() + val range5 = ("ace"[1])..("age"[1]) + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('c', 'd', 'e', 'f', 'g')) { + return "Wrong elements for (\"ace\"[1])..(\"age\"[1]): $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/simpleSteppedDownTo.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/simpleSteppedDownTo.kt new file mode 100644 index 00000000000..2b5ad22293a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/simpleSteppedDownTo.kt @@ -0,0 +1,57 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = 9 downTo 3 step 2 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(9, 7, 5, 3)) { + return "Wrong elements for 9 downTo 3 step 2: $list1" + } + + val list2 = ArrayList() + val range2 = 9.toByte() downTo 3.toByte() step 2 + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(9, 7, 5, 3)) { + return "Wrong elements for 9.toByte() downTo 3.toByte() step 2: $list2" + } + + val list3 = ArrayList() + val range3 = 9.toShort() downTo 3.toShort() step 2 + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(9, 7, 5, 3)) { + return "Wrong elements for 9.toShort() downTo 3.toShort() step 2: $list3" + } + + val list4 = ArrayList() + val range4 = 9.toLong() downTo 3.toLong() step 2.toLong() + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(9, 7, 5, 3)) { + return "Wrong elements for 9.toLong() downTo 3.toLong() step 2.toLong(): $list4" + } + + val list5 = ArrayList() + val range5 = 'g' downTo 'c' step 2 + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('g', 'e', 'c')) { + return "Wrong elements for 'g' downTo 'c' step 2: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/expression/simpleSteppedRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/expression/simpleSteppedRange.kt new file mode 100644 index 00000000000..132a8fc2a88 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/expression/simpleSteppedRange.kt @@ -0,0 +1,57 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + val range1 = 3..9 step 2 + for (i in range1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(3, 5, 7, 9)) { + return "Wrong elements for 3..9 step 2: $list1" + } + + val list2 = ArrayList() + val range2 = 3.toByte()..9.toByte() step 2 + for (i in range2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(3, 5, 7, 9)) { + return "Wrong elements for 3.toByte()..9.toByte() step 2: $list2" + } + + val list3 = ArrayList() + val range3 = 3.toShort()..9.toShort() step 2 + for (i in range3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(3, 5, 7, 9)) { + return "Wrong elements for 3.toShort()..9.toShort() step 2: $list3" + } + + val list4 = ArrayList() + val range4 = 3.toLong()..9.toLong() step 2.toLong() + for (i in range4) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(3, 5, 7, 9)) { + return "Wrong elements for 3.toLong()..9.toLong() step 2.toLong(): $list4" + } + + val list5 = ArrayList() + val range5 = 'c'..'g' step 2 + for (i in range5) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('c', 'e', 'g')) { + return "Wrong elements for 'c'..'g' step 2: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forByteProgressionWithIntIncrement.kt b/backend.native/tests/external/codegen/blackbox/ranges/forByteProgressionWithIntIncrement.kt new file mode 100644 index 00000000000..8596acc44fd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forByteProgressionWithIntIncrement.kt @@ -0,0 +1,9 @@ +// WITH_RUNTIME + +fun box(): String { + for (element in 5.toByte()..1.toByte() step 255) { + return "Fail: iterating over an empty progression, element: $element" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInDownTo/forIntInDownTo.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInDownTo/forIntInDownTo.kt new file mode 100644 index 00000000000..fd046640e37 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInDownTo/forIntInDownTo.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + var sum = 0 + for (i in 4 downTo 1) { + sum = sum * 10 + i + } + assertEquals(4321, sum) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInDownTo/forIntInNonOptimizedDownTo.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInDownTo/forIntInNonOptimizedDownTo.kt new file mode 100644 index 00000000000..45214ff7d0e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInDownTo/forIntInNonOptimizedDownTo.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + var sum = 0 + val dt = 4 downTo 1 + for (i in dt) { + sum = sum * 10 + i + } + assertEquals(4321, sum) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInDownTo/forLongInDownTo.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInDownTo/forLongInDownTo.kt new file mode 100644 index 00000000000..4d1e9793cce --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInDownTo/forLongInDownTo.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + var sum = 0L + for (i in 4L downTo 1L) { + sum = sum * 10L + i + } + assertEquals(4321L, sum) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInDownTo/forNullableIntInDownTo.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInDownTo/forNullableIntInDownTo.kt new file mode 100644 index 00000000000..26109378c1b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInDownTo/forNullableIntInDownTo.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + var sum = 0 + for (i: Int? in 4 downTo 1) { + sum = sum * 10 + (i ?: 0) + } + assertEquals(4321, sum) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInCharSequenceIndices.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInCharSequenceIndices.kt new file mode 100644 index 00000000000..1600771fa32 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInCharSequenceIndices.kt @@ -0,0 +1,16 @@ +// WITH_RUNTIME + +fun test(s: CharSequence): Int { + var result = 0 + for (i in s.indices) { + result = result * 10 + (i + 1) + } + return result +} + +fun box(): String { + val test = test("abcd") + if (test != 1234) return "Fail: $test" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInCollectionImplicitReceiverIndices.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInCollectionImplicitReceiverIndices.kt new file mode 100644 index 00000000000..ec23e8a7493 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInCollectionImplicitReceiverIndices.kt @@ -0,0 +1,19 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun Collection.sumIndices(): Int { + var sum = 0 + for (i in indices) { + sum += i + } + return sum +} + +fun box(): String { + val list = listOf(0, 0, 0, 0) + val sum = list.sumIndices() + assertEquals(6, sum) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInCollectionIndices.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInCollectionIndices.kt new file mode 100644 index 00000000000..f4b018a1ee8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInCollectionIndices.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + var sum = 0 + for (i in listOf(0, 0, 0, 0).indices) { + sum += i + } + assertEquals(6, sum) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInNonOptimizedIndices.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInNonOptimizedIndices.kt new file mode 100644 index 00000000000..b46b4812732 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInNonOptimizedIndices.kt @@ -0,0 +1,18 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun sumIndices(coll: Collection<*>?): Int { + var sum = 0 + for (i in coll?.indices ?: return 0) { + sum += i + } + return sum +} + +fun box(): String { + assertEquals(6, sumIndices(listOf(0, 0, 0, 0))) + assertEquals(0, sumIndices(null)) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInObjectArrayIndices.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInObjectArrayIndices.kt new file mode 100644 index 00000000000..db45263759f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInObjectArrayIndices.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + var sum = 0 + for (i in arrayOf("", "", "", "").indices) { + sum += i + } + assertEquals(6, sum) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInPrimitiveArrayIndices.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInPrimitiveArrayIndices.kt new file mode 100644 index 00000000000..e1e5fb603d7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forInPrimitiveArrayIndices.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun box(): String { + var sum = 0 + for (i in intArrayOf(0, 0, 0, 0).indices) { + sum += i + } + assertEquals(6, sum) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forNullableIntInArrayIndices.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forNullableIntInArrayIndices.kt new file mode 100644 index 00000000000..2fb6c207bda --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forNullableIntInArrayIndices.kt @@ -0,0 +1,16 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun suppressBoxingOptimization(ni: Int?) {} + +fun box(): String { + var sum = 0 + for (i: Int? in arrayOf("", "", "", "").indices) { + suppressBoxingOptimization(i) + sum += i ?: 0 + } + assertEquals(6, sum) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forNullableIntInCollectionIndices.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forNullableIntInCollectionIndices.kt new file mode 100644 index 00000000000..295f66bf5c9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/forNullableIntInCollectionIndices.kt @@ -0,0 +1,16 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun suppressBoxingOptimization(ni: Int?) {} + +fun box(): String { + var sum = 0 + for (i: Int? in listOf("", "", "", "").indices) { + suppressBoxingOptimization(i) + sum += i ?: 0 + } + assertEquals(6, sum) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt12983_forInGenericArrayIndices.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt12983_forInGenericArrayIndices.kt new file mode 100644 index 00000000000..a702ad58de0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt12983_forInGenericArrayIndices.kt @@ -0,0 +1,22 @@ +// WITH_RUNTIME + +abstract class BaseGeneric(val t: T) { + abstract fun iterate() +} + +class Derived(array: Array) : BaseGeneric>(array) { + var test = 0 + + override fun iterate() { + test = 0 + for (i in t.indices) { + test = test * 10 + (i + 1) + } + } +} + +fun box(): String { + val t = Derived(arrayOf("", "", "", "")) + t.iterate() + return if (t.test == 1234) "OK" else "Fail: ${t.test}" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt12983_forInGenericCollectionIndices.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt12983_forInGenericCollectionIndices.kt new file mode 100644 index 00000000000..6a66952d7d5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt12983_forInGenericCollectionIndices.kt @@ -0,0 +1,22 @@ +// WITH_RUNTIME + +abstract class BaseGeneric(val t: T) { + abstract fun iterate() +} + +class Derived(t: List) : BaseGeneric>(t) { + var test = 0 + + override fun iterate() { + test = 0 + for (i in t.indices) { + test = test * 10 + (i + 1) + } + } +} + +fun box(): String { + val t = Derived(listOf("", "", "", "")) + t.iterate() + return if (t.test == 1234) "OK" else "Fail: ${t.test}" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt12983_forInSpecificArrayIndices.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt12983_forInSpecificArrayIndices.kt new file mode 100644 index 00000000000..1ff6d06f18a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt12983_forInSpecificArrayIndices.kt @@ -0,0 +1,22 @@ +// WITH_RUNTIME + +abstract class BaseGeneric(val t: T) { + abstract fun iterate() +} + +class Derived(array: DoubleArray) : BaseGeneric(array) { + var test = 0 + + override fun iterate() { + test = 0 + for (i in t.indices) { + test = test * 10 + (i + 1) + } + } +} + +fun box(): String { + val t = Derived(doubleArrayOf(0.0, 0.0, 0.0, 0.0)) + t.iterate() + return if (t.test == 1234) "OK" else "Fail: ${t.test}" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt12983_forInSpecificCollectionIndices.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt12983_forInSpecificCollectionIndices.kt new file mode 100644 index 00000000000..adeb7decaed --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt12983_forInSpecificCollectionIndices.kt @@ -0,0 +1,22 @@ +// WITH_RUNTIME + +abstract class BaseGeneric(val t: T) { + abstract fun iterate() +} + +class Derived(t: List) : BaseGeneric>(t) { + var test = 0 + + override fun iterate() { + test = 0 + for (i in t.indices) { + test = test * 10 + (i + 1) + } + } +} + +fun box(): String { + val t = Derived(listOf(1, 2, 3, 4)) + t.iterate() + return if (t.test == 1234) "OK" else "Fail: ${t.test}" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt13241_Array.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt13241_Array.kt new file mode 100644 index 00000000000..0f73b57e33c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt13241_Array.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun test(x: Any): Int { + var sum = 0 + if (x is IntArray) { + for (i in x.indices) { + sum = sum * 10 + i + } + } + return sum +} + +fun box(): String { + assertEquals(123, test(intArrayOf(0, 0, 0, 0))) + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt13241_CharSequence.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt13241_CharSequence.kt new file mode 100644 index 00000000000..a0d45d7698e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt13241_CharSequence.kt @@ -0,0 +1,18 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun test(x: Any): Int { + var sum = 0 + if (x is String) { + for (i in x.indices) { + sum = sum * 10 + i + } + } + return sum +} + +fun box(): String { + assertEquals(123, test("0000")) + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt13241_Collection.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt13241_Collection.kt new file mode 100644 index 00000000000..9bd4610d351 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInIndices/kt13241_Collection.kt @@ -0,0 +1,18 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun test(x: Any): Int { + var sum = 0 + if (x is List<*>) { + for (i in x.indices) { + sum = sum * 10 + i + } + } + return sum +} + +fun box(): String { + assertEquals(123, test(listOf(0, 0, 0, 0))) + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forInRangeWithImplicitReceiver.kt b/backend.native/tests/external/codegen/blackbox/ranges/forInRangeWithImplicitReceiver.kt new file mode 100644 index 00000000000..a29e5a77e5e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forInRangeWithImplicitReceiver.kt @@ -0,0 +1,17 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun Int.digitsUpto(end: Int): Int { + var sum = 0 + for (i in rangeTo(end)) { + sum = sum*10 + i + } + return sum +} + +fun box(): String { + assertEquals(1234, 1.digitsUpto(4)) + return "OK" +} + diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forIntRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/forIntRange.kt new file mode 100644 index 00000000000..1dd52f48533 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forIntRange.kt @@ -0,0 +1,15 @@ +// WITH_RUNTIME + +fun box() : String { + val a = arrayOfNulls(3) + a[0] = "a" + a[1] = "b" + a[2] = "c" + + var result = 0 + for(i in a.indices) { + result += i + } + if (result != 3) return "FAIL" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/forNullableIntInRangeWithImplicitReceiver.kt b/backend.native/tests/external/codegen/blackbox/ranges/forNullableIntInRangeWithImplicitReceiver.kt new file mode 100644 index 00000000000..8f9a4534ea6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/forNullableIntInRangeWithImplicitReceiver.kt @@ -0,0 +1,20 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun suppressBoxingOptimization(ni: Int?) {} + +fun Int.digitsUpto(end: Int): Int { + var sum = 0 + for (i: Int? in rangeTo(end)) { + suppressBoxingOptimization(i) + sum = sum*10 + i!! + } + return sum +} + +fun box(): String { + assertEquals(1234, 1.digitsUpto(4)) + return "OK" +} + diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/emptyDownto.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/emptyDownto.kt new file mode 100644 index 00000000000..ac36fbd5d62 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/emptyDownto.kt @@ -0,0 +1,52 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in 5 downTo 10) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for 5 downTo 10: $list1" + } + + val list2 = ArrayList() + for (i in 5.toByte() downTo 10.toByte()) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for 5.toByte() downTo 10.toByte(): $list2" + } + + val list3 = ArrayList() + for (i in 5.toShort() downTo 10.toShort()) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for 5.toShort() downTo 10.toShort(): $list3" + } + + val list4 = ArrayList() + for (i in 5.toLong() downTo 10.toLong()) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for 5.toLong() downTo 10.toLong(): $list4" + } + + val list5 = ArrayList() + for (i in 'a' downTo 'z') { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for 'a' downTo 'z': $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/emptyRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/emptyRange.kt new file mode 100644 index 00000000000..e977c4b9461 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/emptyRange.kt @@ -0,0 +1,52 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in 10..5) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for 10..5: $list1" + } + + val list2 = ArrayList() + for (i in 10.toByte()..(-5).toByte()) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for 10.toByte()..(-5).toByte(): $list2" + } + + val list3 = ArrayList() + for (i in 10.toShort()..(-5).toShort()) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for 10.toShort()..(-5).toShort(): $list3" + } + + val list4 = ArrayList() + for (i in 10.toLong()..-5.toLong()) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for 10.toLong()..-5.toLong(): $list4" + } + + val list5 = ArrayList() + for (i in 'z'..'a') { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for 'z'..'a': $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/inexactDownToMinValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/inexactDownToMinValue.kt new file mode 100644 index 00000000000..a66daa50878 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/inexactDownToMinValue.kt @@ -0,0 +1,66 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in (MinI + 5) downTo MinI step 3) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(MinI + 5, MinI + 2)) { + return "Wrong elements for (MinI + 5) downTo MinI step 3: $list1" + } + + val list2 = ArrayList() + for (i in (MinB + 5).toByte() downTo MinB step 3) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf((MinB + 5).toInt(), (MinB + 2).toInt())) { + return "Wrong elements for (MinB + 5).toByte() downTo MinB step 3: $list2" + } + + val list3 = ArrayList() + for (i in (MinS + 5).toShort() downTo MinS step 3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf((MinS + 5).toInt(), (MinS + 2).toInt())) { + return "Wrong elements for (MinS + 5).toShort() downTo MinS step 3: $list3" + } + + val list4 = ArrayList() + for (i in (MinL + 5).toLong() downTo MinL step 3) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf((MinL + 5).toLong(), (MinL + 2).toLong())) { + return "Wrong elements for (MinL + 5).toLong() downTo MinL step 3: $list4" + } + + val list5 = ArrayList() + for (i in (MinC + 5) downTo MinC step 3) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf((MinC + 5), (MinC + 2))) { + return "Wrong elements for (MinC + 5) downTo MinC step 3: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/inexactSteppedDownTo.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/inexactSteppedDownTo.kt new file mode 100644 index 00000000000..1696d7a1cb9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/inexactSteppedDownTo.kt @@ -0,0 +1,52 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in 8 downTo 3 step 2) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(8, 6, 4)) { + return "Wrong elements for 8 downTo 3 step 2: $list1" + } + + val list2 = ArrayList() + for (i in 8.toByte() downTo 3.toByte() step 2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(8, 6, 4)) { + return "Wrong elements for 8.toByte() downTo 3.toByte() step 2: $list2" + } + + val list3 = ArrayList() + for (i in 8.toShort() downTo 3.toShort() step 2) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(8, 6, 4)) { + return "Wrong elements for 8.toShort() downTo 3.toShort() step 2: $list3" + } + + val list4 = ArrayList() + for (i in 8.toLong() downTo 3.toLong() step 2.toLong()) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(8, 6, 4)) { + return "Wrong elements for 8.toLong() downTo 3.toLong() step 2.toLong(): $list4" + } + + val list5 = ArrayList() + for (i in 'd' downTo 'a' step 2) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('d', 'b')) { + return "Wrong elements for 'd' downTo 'a' step 2: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/inexactSteppedRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/inexactSteppedRange.kt new file mode 100644 index 00000000000..b7aec1243ad --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/inexactSteppedRange.kt @@ -0,0 +1,52 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in 3..8 step 2) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(3, 5, 7)) { + return "Wrong elements for 3..8 step 2: $list1" + } + + val list2 = ArrayList() + for (i in 3.toByte()..8.toByte() step 2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(3, 5, 7)) { + return "Wrong elements for 3.toByte()..8.toByte() step 2: $list2" + } + + val list3 = ArrayList() + for (i in 3.toShort()..8.toShort() step 2) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(3, 5, 7)) { + return "Wrong elements for 3.toShort()..8.toShort() step 2: $list3" + } + + val list4 = ArrayList() + for (i in 3.toLong()..8.toLong() step 2.toLong()) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(3, 5, 7)) { + return "Wrong elements for 3.toLong()..8.toLong() step 2.toLong(): $list4" + } + + val list5 = ArrayList() + for (i in 'a'..'d' step 2) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('a', 'c')) { + return "Wrong elements for 'a'..'d' step 2: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/inexactToMaxValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/inexactToMaxValue.kt new file mode 100644 index 00000000000..a55c76920aa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/inexactToMaxValue.kt @@ -0,0 +1,66 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in (MaxI - 5)..MaxI step 3) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(MaxI - 5, MaxI - 2)) { + return "Wrong elements for (MaxI - 5)..MaxI step 3: $list1" + } + + val list2 = ArrayList() + for (i in (MaxB - 5).toByte()..MaxB step 3) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf((MaxB - 5).toInt(), (MaxB - 2).toInt())) { + return "Wrong elements for (MaxB - 5).toByte()..MaxB step 3: $list2" + } + + val list3 = ArrayList() + for (i in (MaxS - 5).toShort()..MaxS step 3) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf((MaxS - 5).toInt(), (MaxS - 2).toInt())) { + return "Wrong elements for (MaxS - 5).toShort()..MaxS step 3: $list3" + } + + val list4 = ArrayList() + for (i in (MaxL - 5).toLong()..MaxL step 3) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf((MaxL - 5).toLong(), (MaxL - 2).toLong())) { + return "Wrong elements for (MaxL - 5).toLong()..MaxL step 3: $list4" + } + + val list5 = ArrayList() + for (i in (MaxC - 5)..MaxC step 3) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf((MaxC - 5), (MaxC - 2))) { + return "Wrong elements for (MaxC - 5)..MaxC step 3: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/maxValueMinusTwoToMaxValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/maxValueMinusTwoToMaxValue.kt new file mode 100644 index 00000000000..1c76fabe3cc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/maxValueMinusTwoToMaxValue.kt @@ -0,0 +1,66 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in (MaxI - 2)..MaxI) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(MaxI - 2, MaxI - 1, MaxI)) { + return "Wrong elements for (MaxI - 2)..MaxI: $list1" + } + + val list2 = ArrayList() + for (i in (MaxB - 2).toByte()..MaxB) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf((MaxB - 2).toInt(), (MaxB - 1).toInt(), MaxB.toInt())) { + return "Wrong elements for (MaxB - 2).toByte()..MaxB: $list2" + } + + val list3 = ArrayList() + for (i in (MaxS - 2).toShort()..MaxS) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf((MaxS - 2).toInt(), (MaxS - 1).toInt(), MaxS.toInt())) { + return "Wrong elements for (MaxS - 2).toShort()..MaxS: $list3" + } + + val list4 = ArrayList() + for (i in (MaxL - 2).toLong()..MaxL) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf((MaxL - 2).toLong(), (MaxL - 1).toLong(), MaxL)) { + return "Wrong elements for (MaxL - 2).toLong()..MaxL: $list4" + } + + val list5 = ArrayList() + for (i in (MaxC - 2)..MaxC) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf((MaxC - 2), (MaxC - 1), MaxC)) { + return "Wrong elements for (MaxC - 2)..MaxC: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/maxValueToMaxValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/maxValueToMaxValue.kt new file mode 100644 index 00000000000..cdedbbb8c7b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/maxValueToMaxValue.kt @@ -0,0 +1,66 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in MaxI..MaxI) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(MaxI)) { + return "Wrong elements for MaxI..MaxI: $list1" + } + + val list2 = ArrayList() + for (i in MaxB..MaxB) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(MaxB.toInt())) { + return "Wrong elements for MaxB..MaxB: $list2" + } + + val list3 = ArrayList() + for (i in MaxS..MaxS) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(MaxS.toInt())) { + return "Wrong elements for MaxS..MaxS: $list3" + } + + val list4 = ArrayList() + for (i in MaxL..MaxL) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(MaxL)) { + return "Wrong elements for MaxL..MaxL: $list4" + } + + val list5 = ArrayList() + for (i in MaxC..MaxC) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf(MaxC)) { + return "Wrong elements for MaxC..MaxC: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/maxValueToMinValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/maxValueToMinValue.kt new file mode 100644 index 00000000000..2439eab980c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/maxValueToMinValue.kt @@ -0,0 +1,66 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in MaxI..MinI) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for MaxI..MinI: $list1" + } + + val list2 = ArrayList() + for (i in MaxB..MinB) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for MaxB..MinB: $list2" + } + + val list3 = ArrayList() + for (i in MaxS..MinS) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for MaxS..MinS: $list3" + } + + val list4 = ArrayList() + for (i in MaxL..MinL) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for MaxL..MinL: $list4" + } + + val list5 = ArrayList() + for (i in MaxC..MinC) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for MaxC..MinC: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/oneElementDownTo.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/oneElementDownTo.kt new file mode 100644 index 00000000000..9a5fd5f8589 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/oneElementDownTo.kt @@ -0,0 +1,52 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in 5 downTo 5) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(5)) { + return "Wrong elements for 5 downTo 5: $list1" + } + + val list2 = ArrayList() + for (i in 5.toByte() downTo 5.toByte()) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(5)) { + return "Wrong elements for 5.toByte() downTo 5.toByte(): $list2" + } + + val list3 = ArrayList() + for (i in 5.toShort() downTo 5.toShort()) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(5)) { + return "Wrong elements for 5.toShort() downTo 5.toShort(): $list3" + } + + val list4 = ArrayList() + for (i in 5.toLong() downTo 5.toLong()) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(5.toLong())) { + return "Wrong elements for 5.toLong() downTo 5.toLong(): $list4" + } + + val list5 = ArrayList() + for (i in 'k' downTo 'k') { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('k')) { + return "Wrong elements for 'k' downTo 'k': $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/oneElementRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/oneElementRange.kt new file mode 100644 index 00000000000..3d7dc4fec09 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/oneElementRange.kt @@ -0,0 +1,52 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in 5..5) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(5)) { + return "Wrong elements for 5..5: $list1" + } + + val list2 = ArrayList() + for (i in 5.toByte()..5.toByte()) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(5)) { + return "Wrong elements for 5.toByte()..5.toByte(): $list2" + } + + val list3 = ArrayList() + for (i in 5.toShort()..5.toShort()) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(5)) { + return "Wrong elements for 5.toShort()..5.toShort(): $list3" + } + + val list4 = ArrayList() + for (i in 5.toLong()..5.toLong()) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(5.toLong())) { + return "Wrong elements for 5.toLong()..5.toLong(): $list4" + } + + val list5 = ArrayList() + for (i in 'k'..'k') { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('k')) { + return "Wrong elements for 'k'..'k': $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/openRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/openRange.kt new file mode 100644 index 00000000000..488600a9207 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/openRange.kt @@ -0,0 +1,52 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in 1 until 5) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(1, 2, 3, 4)) { + return "Wrong elements for 1 until 5: $list1" + } + + val list2 = ArrayList() + for (i in 1.toByte() until 5.toByte()) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(1, 2, 3, 4)) { + return "Wrong elements for 1.toByte() until 5.toByte(): $list2" + } + + val list3 = ArrayList() + for (i in 1.toShort() until 5.toShort()) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(1, 2, 3, 4)) { + return "Wrong elements for 1.toShort() until 5.toShort(): $list3" + } + + val list4 = ArrayList() + for (i in 1.toLong() until 5.toLong()) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(1, 2, 3, 4)) { + return "Wrong elements for 1.toLong() until 5.toLong(): $list4" + } + + val list5 = ArrayList() + for (i in 'a' until 'd') { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('a', 'b', 'c')) { + return "Wrong elements for 'a' until 'd': $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/progressionDownToMinValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/progressionDownToMinValue.kt new file mode 100644 index 00000000000..fccb2044c9f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/progressionDownToMinValue.kt @@ -0,0 +1,66 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in (MinI + 2) downTo MinI step 1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(MinI + 2, MinI + 1, MinI)) { + return "Wrong elements for (MinI + 2) downTo MinI step 1: $list1" + } + + val list2 = ArrayList() + for (i in (MinB + 2).toByte() downTo MinB step 1) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf((MinB + 2).toInt(), (MinB + 1).toInt(), MinB.toInt())) { + return "Wrong elements for (MinB + 2).toByte() downTo MinB step 1: $list2" + } + + val list3 = ArrayList() + for (i in (MinS + 2).toShort() downTo MinS step 1) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf((MinS + 2).toInt(), (MinS + 1).toInt(), MinS.toInt())) { + return "Wrong elements for (MinS + 2).toShort() downTo MinS step 1: $list3" + } + + val list4 = ArrayList() + for (i in (MinL + 2).toLong() downTo MinL step 1) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf((MinL + 2).toLong(), (MinL + 1).toLong(), MinL)) { + return "Wrong elements for (MinL + 2).toLong() downTo MinL step 1: $list4" + } + + val list5 = ArrayList() + for (i in (MinC + 2) downTo MinC step 1) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf((MinC + 2), (MinC + 1), MinC)) { + return "Wrong elements for (MinC + 2) downTo MinC step 1: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/progressionMaxValueMinusTwoToMaxValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/progressionMaxValueMinusTwoToMaxValue.kt new file mode 100644 index 00000000000..7c81034ef7a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/progressionMaxValueMinusTwoToMaxValue.kt @@ -0,0 +1,66 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in (MaxI - 2)..MaxI step 2) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(MaxI - 2, MaxI)) { + return "Wrong elements for (MaxI - 2)..MaxI step 2: $list1" + } + + val list2 = ArrayList() + for (i in (MaxB - 2).toByte()..MaxB step 2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf((MaxB - 2).toInt(), MaxB.toInt())) { + return "Wrong elements for (MaxB - 2).toByte()..MaxB step 2: $list2" + } + + val list3 = ArrayList() + for (i in (MaxS - 2).toShort()..MaxS step 2) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf((MaxS - 2).toInt(), MaxS.toInt())) { + return "Wrong elements for (MaxS - 2).toShort()..MaxS step 2: $list3" + } + + val list4 = ArrayList() + for (i in (MaxL - 2).toLong()..MaxL step 2) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf((MaxL - 2).toLong(), MaxL)) { + return "Wrong elements for (MaxL - 2).toLong()..MaxL step 2: $list4" + } + + val list5 = ArrayList() + for (i in (MaxC - 2)..MaxC step 2) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf((MaxC - 2), MaxC)) { + return "Wrong elements for (MaxC - 2)..MaxC step 2: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/progressionMaxValueToMaxValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/progressionMaxValueToMaxValue.kt new file mode 100644 index 00000000000..4c4555326fc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/progressionMaxValueToMaxValue.kt @@ -0,0 +1,66 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in MaxI..MaxI step 1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(MaxI)) { + return "Wrong elements for MaxI..MaxI step 1: $list1" + } + + val list2 = ArrayList() + for (i in MaxB..MaxB step 1) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(MaxB.toInt())) { + return "Wrong elements for MaxB..MaxB step 1: $list2" + } + + val list3 = ArrayList() + for (i in MaxS..MaxS step 1) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(MaxS.toInt())) { + return "Wrong elements for MaxS..MaxS step 1: $list3" + } + + val list4 = ArrayList() + for (i in MaxL..MaxL step 1) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(MaxL)) { + return "Wrong elements for MaxL..MaxL step 1: $list4" + } + + val list5 = ArrayList() + for (i in MaxC..MaxC step 1) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf(MaxC)) { + return "Wrong elements for MaxC..MaxC step 1: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/progressionMaxValueToMinValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/progressionMaxValueToMinValue.kt new file mode 100644 index 00000000000..cd29a83cb6f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/progressionMaxValueToMinValue.kt @@ -0,0 +1,66 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in MaxI..MinI step 1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for MaxI..MinI step 1: $list1" + } + + val list2 = ArrayList() + for (i in MaxB..MinB step 1) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for MaxB..MinB step 1: $list2" + } + + val list3 = ArrayList() + for (i in MaxS..MinS step 1) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for MaxS..MinS step 1: $list3" + } + + val list4 = ArrayList() + for (i in MaxL..MinL step 1) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for MaxL..MinL step 1: $list4" + } + + val list5 = ArrayList() + for (i in MaxC..MinC step 1) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for MaxC..MinC step 1: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/progressionMinValueToMinValue.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/progressionMinValueToMinValue.kt new file mode 100644 index 00000000000..f0b5a5a9041 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/progressionMinValueToMinValue.kt @@ -0,0 +1,66 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in MinI..MinI step 1) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(MinI)) { + return "Wrong elements for MinI..MinI step 1: $list1" + } + + val list2 = ArrayList() + for (i in MinB..MinB step 1) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(MinB.toInt())) { + return "Wrong elements for MinB..MinB step 1: $list2" + } + + val list3 = ArrayList() + for (i in MinS..MinS step 1) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(MinS.toInt())) { + return "Wrong elements for MinS..MinS step 1: $list3" + } + + val list4 = ArrayList() + for (i in MinL..MinL step 1) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(MinL)) { + return "Wrong elements for MinL..MinL step 1: $list4" + } + + val list5 = ArrayList() + for (i in MinC..MinC step 1) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf(MinC)) { + return "Wrong elements for MinC..MinC step 1: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedBackSequence.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedBackSequence.kt new file mode 100644 index 00000000000..f4cd7ae0df6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedBackSequence.kt @@ -0,0 +1,52 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in (5 downTo 3).reversed()) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(3, 4, 5)) { + return "Wrong elements for (5 downTo 3).reversed(): $list1" + } + + val list2 = ArrayList() + for (i in (5.toByte() downTo 3.toByte()).reversed()) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(3, 4, 5)) { + return "Wrong elements for (5.toByte() downTo 3.toByte()).reversed(): $list2" + } + + val list3 = ArrayList() + for (i in (5.toShort() downTo 3.toShort()).reversed()) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(3, 4, 5)) { + return "Wrong elements for (5.toShort() downTo 3.toShort()).reversed(): $list3" + } + + val list4 = ArrayList() + for (i in (5.toLong() downTo 3.toLong()).reversed()) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(3, 4, 5)) { + return "Wrong elements for (5.toLong() downTo 3.toLong()).reversed(): $list4" + } + + val list5 = ArrayList() + for (i in ('c' downTo 'a').reversed()) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('a', 'b', 'c')) { + return "Wrong elements for ('c' downTo 'a').reversed(): $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedEmptyBackSequence.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedEmptyBackSequence.kt new file mode 100644 index 00000000000..9c2bab57838 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedEmptyBackSequence.kt @@ -0,0 +1,52 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in (3 downTo 5).reversed()) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for (3 downTo 5).reversed(): $list1" + } + + val list2 = ArrayList() + for (i in (3.toByte() downTo 5.toByte()).reversed()) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for (3.toByte() downTo 5.toByte()).reversed(): $list2" + } + + val list3 = ArrayList() + for (i in (3.toShort() downTo 5.toShort()).reversed()) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for (3.toShort() downTo 5.toShort()).reversed(): $list3" + } + + val list4 = ArrayList() + for (i in (3.toLong() downTo 5.toLong()).reversed()) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for (3.toLong() downTo 5.toLong()).reversed(): $list4" + } + + val list5 = ArrayList() + for (i in ('a' downTo 'c').reversed()) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for ('a' downTo 'c').reversed(): $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedEmptyRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedEmptyRange.kt new file mode 100644 index 00000000000..c2442883533 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedEmptyRange.kt @@ -0,0 +1,52 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in (5..3).reversed()) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for (5..3).reversed(): $list1" + } + + val list2 = ArrayList() + for (i in (5.toByte()..3.toByte()).reversed()) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for (5.toByte()..3.toByte()).reversed(): $list2" + } + + val list3 = ArrayList() + for (i in (5.toShort()..3.toShort()).reversed()) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for (5.toShort()..3.toShort()).reversed(): $list3" + } + + val list4 = ArrayList() + for (i in (5.toLong()..3.toLong()).reversed()) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for (5.toLong()..3.toLong()).reversed(): $list4" + } + + val list5 = ArrayList() + for (i in ('c'..'a').reversed()) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for ('c'..'a').reversed(): $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedInexactSteppedDownTo.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedInexactSteppedDownTo.kt new file mode 100644 index 00000000000..63c431ab3c8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedInexactSteppedDownTo.kt @@ -0,0 +1,52 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in (8 downTo 3 step 2).reversed()) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(4, 6, 8)) { + return "Wrong elements for (8 downTo 3 step 2).reversed(): $list1" + } + + val list2 = ArrayList() + for (i in (8.toByte() downTo 3.toByte() step 2).reversed()) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(4, 6, 8)) { + return "Wrong elements for (8.toByte() downTo 3.toByte() step 2).reversed(): $list2" + } + + val list3 = ArrayList() + for (i in (8.toShort() downTo 3.toShort() step 2).reversed()) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(4, 6, 8)) { + return "Wrong elements for (8.toShort() downTo 3.toShort() step 2).reversed(): $list3" + } + + val list4 = ArrayList() + for (i in (8.toLong() downTo 3.toLong() step 2.toLong()).reversed()) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(4, 6, 8)) { + return "Wrong elements for (8.toLong() downTo 3.toLong() step 2.toLong()).reversed(): $list4" + } + + val list5 = ArrayList() + for (i in ('d' downTo 'a' step 2).reversed()) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('b', 'd')) { + return "Wrong elements for ('d' downTo 'a' step 2).reversed(): $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedRange.kt new file mode 100644 index 00000000000..1d4e6649437 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedRange.kt @@ -0,0 +1,43 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in (3..5).reversed()) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(5, 4, 3)) { + return "Wrong elements for (3..5).reversed(): $list1" + } + + val list2 = ArrayList() + for (i in (3.toShort()..5.toShort()).reversed()) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(5, 4, 3)) { + return "Wrong elements for (3.toShort()..5.toShort()).reversed(): $list2" + } + + val list3 = ArrayList() + for (i in (3.toLong()..5.toLong()).reversed()) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(5, 4, 3)) { + return "Wrong elements for (3.toLong()..5.toLong()).reversed(): $list3" + } + + val list4 = ArrayList() + for (i in ('a'..'c').reversed()) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf('c', 'b', 'a')) { + return "Wrong elements for ('a'..'c').reversed(): $list4" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedSimpleSteppedRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedSimpleSteppedRange.kt new file mode 100644 index 00000000000..be85c5020c0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/reversedSimpleSteppedRange.kt @@ -0,0 +1,52 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in (3..9 step 2).reversed()) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(9, 7, 5, 3)) { + return "Wrong elements for (3..9 step 2).reversed(): $list1" + } + + val list2 = ArrayList() + for (i in (3.toByte()..9.toByte() step 2).reversed()) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(9, 7, 5, 3)) { + return "Wrong elements for (3.toByte()..9.toByte() step 2).reversed(): $list2" + } + + val list3 = ArrayList() + for (i in (3.toShort()..9.toShort() step 2).reversed()) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(9, 7, 5, 3)) { + return "Wrong elements for (3.toShort()..9.toShort() step 2).reversed(): $list3" + } + + val list4 = ArrayList() + for (i in (3.toLong()..9.toLong() step 2.toLong()).reversed()) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(9, 7, 5, 3)) { + return "Wrong elements for (3.toLong()..9.toLong() step 2.toLong()).reversed(): $list4" + } + + val list5 = ArrayList() + for (i in ('c'..'g' step 2).reversed()) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('g', 'e', 'c')) { + return "Wrong elements for ('c'..'g' step 2).reversed(): $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/simpleDownTo.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/simpleDownTo.kt new file mode 100644 index 00000000000..13bdb9a25e9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/simpleDownTo.kt @@ -0,0 +1,52 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in 9 downTo 3) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(9, 8, 7, 6, 5, 4, 3)) { + return "Wrong elements for 9 downTo 3: $list1" + } + + val list2 = ArrayList() + for (i in 9.toByte() downTo 3.toByte()) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(9, 8, 7, 6, 5, 4, 3)) { + return "Wrong elements for 9.toByte() downTo 3.toByte(): $list2" + } + + val list3 = ArrayList() + for (i in 9.toShort() downTo 3.toShort()) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(9, 8, 7, 6, 5, 4, 3)) { + return "Wrong elements for 9.toShort() downTo 3.toShort(): $list3" + } + + val list4 = ArrayList() + for (i in 9.toLong() downTo 3.toLong()) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(9, 8, 7, 6, 5, 4, 3)) { + return "Wrong elements for 9.toLong() downTo 3.toLong(): $list4" + } + + val list5 = ArrayList() + for (i in 'g' downTo 'c') { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('g', 'f', 'e', 'd', 'c')) { + return "Wrong elements for 'g' downTo 'c': $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/simpleRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/simpleRange.kt new file mode 100644 index 00000000000..3a074a477d1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/simpleRange.kt @@ -0,0 +1,52 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in 3..9) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(3, 4, 5, 6, 7, 8, 9)) { + return "Wrong elements for 3..9: $list1" + } + + val list2 = ArrayList() + for (i in 3.toByte()..9.toByte()) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(3, 4, 5, 6, 7, 8, 9)) { + return "Wrong elements for 3.toByte()..9.toByte(): $list2" + } + + val list3 = ArrayList() + for (i in 3.toShort()..9.toShort()) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(3, 4, 5, 6, 7, 8, 9)) { + return "Wrong elements for 3.toShort()..9.toShort(): $list3" + } + + val list4 = ArrayList() + for (i in 3.toLong()..9.toLong()) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(3, 4, 5, 6, 7, 8, 9)) { + return "Wrong elements for 3.toLong()..9.toLong(): $list4" + } + + val list5 = ArrayList() + for (i in 'c'..'g') { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('c', 'd', 'e', 'f', 'g')) { + return "Wrong elements for 'c'..'g': $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/simpleRangeWithNonConstantEnds.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/simpleRangeWithNonConstantEnds.kt new file mode 100644 index 00000000000..b242f085369 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/simpleRangeWithNonConstantEnds.kt @@ -0,0 +1,52 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in (1 + 2)..(10 - 1)) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(3, 4, 5, 6, 7, 8, 9)) { + return "Wrong elements for (1 + 2)..(10 - 1): $list1" + } + + val list2 = ArrayList() + for (i in (1.toByte() + 2.toByte()).toByte()..(10.toByte() - 1.toByte()).toByte()) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(3, 4, 5, 6, 7, 8, 9)) { + return "Wrong elements for (1.toByte() + 2.toByte()).toByte()..(10.toByte() - 1.toByte()).toByte(): $list2" + } + + val list3 = ArrayList() + for (i in (1.toShort() + 2.toShort()).toShort()..(10.toShort() - 1.toShort()).toShort()) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(3, 4, 5, 6, 7, 8, 9)) { + return "Wrong elements for (1.toShort() + 2.toShort()).toShort()..(10.toShort() - 1.toShort()).toShort(): $list3" + } + + val list4 = ArrayList() + for (i in (1.toLong() + 2.toLong())..(10.toLong() - 1.toLong())) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(3, 4, 5, 6, 7, 8, 9)) { + return "Wrong elements for (1.toLong() + 2.toLong())..(10.toLong() - 1.toLong()): $list4" + } + + val list5 = ArrayList() + for (i in ("ace"[1])..("age"[1])) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('c', 'd', 'e', 'f', 'g')) { + return "Wrong elements for (\"ace\"[1])..(\"age\"[1]): $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/simpleSteppedDownTo.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/simpleSteppedDownTo.kt new file mode 100644 index 00000000000..62dd8c70251 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/simpleSteppedDownTo.kt @@ -0,0 +1,52 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in 9 downTo 3 step 2) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(9, 7, 5, 3)) { + return "Wrong elements for 9 downTo 3 step 2: $list1" + } + + val list2 = ArrayList() + for (i in 9.toByte() downTo 3.toByte() step 2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(9, 7, 5, 3)) { + return "Wrong elements for 9.toByte() downTo 3.toByte() step 2: $list2" + } + + val list3 = ArrayList() + for (i in 9.toShort() downTo 3.toShort() step 2) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(9, 7, 5, 3)) { + return "Wrong elements for 9.toShort() downTo 3.toShort() step 2: $list3" + } + + val list4 = ArrayList() + for (i in 9.toLong() downTo 3.toLong() step 2.toLong()) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(9, 7, 5, 3)) { + return "Wrong elements for 9.toLong() downTo 3.toLong() step 2.toLong(): $list4" + } + + val list5 = ArrayList() + for (i in 'g' downTo 'c' step 2) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('g', 'e', 'c')) { + return "Wrong elements for 'g' downTo 'c' step 2: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/literal/simpleSteppedRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/literal/simpleSteppedRange.kt new file mode 100644 index 00000000000..4552ee0f9f7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/literal/simpleSteppedRange.kt @@ -0,0 +1,52 @@ +// Auto-generated by org.jetbrains.kotlin.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +// WITH_RUNTIME + + +fun box(): String { + val list1 = ArrayList() + for (i in 3..9 step 2) { + list1.add(i) + if (list1.size > 23) break + } + if (list1 != listOf(3, 5, 7, 9)) { + return "Wrong elements for 3..9 step 2: $list1" + } + + val list2 = ArrayList() + for (i in 3.toByte()..9.toByte() step 2) { + list2.add(i) + if (list2.size > 23) break + } + if (list2 != listOf(3, 5, 7, 9)) { + return "Wrong elements for 3.toByte()..9.toByte() step 2: $list2" + } + + val list3 = ArrayList() + for (i in 3.toShort()..9.toShort() step 2) { + list3.add(i) + if (list3.size > 23) break + } + if (list3 != listOf(3, 5, 7, 9)) { + return "Wrong elements for 3.toShort()..9.toShort() step 2: $list3" + } + + val list4 = ArrayList() + for (i in 3.toLong()..9.toLong() step 2.toLong()) { + list4.add(i) + if (list4.size > 23) break + } + if (list4 != listOf(3, 5, 7, 9)) { + return "Wrong elements for 3.toLong()..9.toLong() step 2.toLong(): $list4" + } + + val list5 = ArrayList() + for (i in 'c'..'g' step 2) { + list5.add(i) + if (list5.size > 23) break + } + if (list5 != listOf('c', 'e', 'g')) { + return "Wrong elements for 'c'..'g' step 2: $list5" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/multiAssignmentIterationOverIntRange.kt b/backend.native/tests/external/codegen/blackbox/ranges/multiAssignmentIterationOverIntRange.kt new file mode 100644 index 00000000000..d8fef0b509a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/multiAssignmentIterationOverIntRange.kt @@ -0,0 +1,23 @@ +// WITH_RUNTIME + +operator fun Int.component1(): String { + return arrayListOf("zero", "one", "two", "three")[this] +} + +operator fun Int.component2(): Int { + return arrayListOf(0, 1, 4, 9)[this] +} + +fun box(): String { + val strings = arrayListOf() + val squares = arrayListOf() + + for ((str, sq) in 1..3) { + strings.add(str) + squares.add(sq) + } + + if (strings != arrayListOf("one", "two", "three")) return "FAIL: $strings" + if (squares != arrayListOf(1, 4, 9)) return "FAIL: $squares" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/ranges/nullableLoopParameter/progressionExpression.kt b/backend.native/tests/external/codegen/blackbox/ranges/nullableLoopParameter/progressionExpression.kt new file mode 100644 index 00000000000..2caf1a33808 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/nullableLoopParameter/progressionExpression.kt @@ -0,0 +1,12 @@ +fun box(): String { + var result = 0 + val intRange: IntProgression = 1..3 + for (i: Int? in intRange) { + result = sum(result, i) + } + return if (result == 6) "OK" else "fail: $result" +} + +fun sum(i: Int, z: Int?): Int { + return i + z!! +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/nullableLoopParameter/rangeExpression.kt b/backend.native/tests/external/codegen/blackbox/ranges/nullableLoopParameter/rangeExpression.kt new file mode 100644 index 00000000000..7cc906c09d2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/nullableLoopParameter/rangeExpression.kt @@ -0,0 +1,12 @@ +fun box(): String { + var result = 0 + val intRange = 1..3 + for (i: Int? in intRange) { + result = sum(result, i) + } + return if (result == 6) "OK" else "fail: $result" +} + +fun sum(i: Int, z: Int?): Int { + return i + z!! +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/nullableLoopParameter/rangeLiteral.kt b/backend.native/tests/external/codegen/blackbox/ranges/nullableLoopParameter/rangeLiteral.kt new file mode 100644 index 00000000000..52713ad8bf7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/nullableLoopParameter/rangeLiteral.kt @@ -0,0 +1,11 @@ +fun box(): String { + var result = 0 + for (i: Int? in 1..3) { + result = sum(result, i) + } + return if (result == 6) "OK" else "fail: $result" +} + +fun sum(i: Int, z: Int?): Int { + return i + z!! +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/ranges/safeCallRangeTo.kt b/backend.native/tests/external/codegen/blackbox/ranges/safeCallRangeTo.kt new file mode 100644 index 00000000000..e1eb200a582 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/ranges/safeCallRangeTo.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun charRange(x: Char?, y: Char) = x?.rangeTo(y) +fun byteRange(x: Byte?, y: Byte) = x?.rangeTo(y) +fun shortRange(x: Short?, y: Short) = x?.rangeTo(y) +fun intRange(x: Int?, y: Int) = x?.rangeTo(y) +fun longRange(x: Long?, y: Long) = x?.rangeTo(y) +fun floatRange(x: Float?, y: Float) = x?.rangeTo(y) +fun dougleRange(x: Double?, y: Double) = x?.rangeTo(y) + +inline fun testSafeRange(x: T, y: T, expectStr: String, safeRange: (T?, T) -> R?) { + val rNull = safeRange(null, y) + assert (rNull == null) { "${T::class.simpleName}: Expected: null, got $rNull" } + + val rxy = safeRange(x, y) + assert (rxy?.toString() == expectStr) { "${T::class.simpleName}: Expected: $expectStr, got $rxy" } +} + +fun box(): String { + testSafeRange('0', '1', "0..1", ::charRange) + testSafeRange(0, 1, "0..1", ::byteRange) + testSafeRange(0, 1, "0..1", ::shortRange) + testSafeRange(0, 1, "0..1", ::intRange) + testSafeRange(0L, 1L, "0..1", ::longRange) + testSafeRange(0.0f, 1.0f, "0.0..1.0", ::floatRange) + testSafeRange(0.0, 1.0, "0.0..1.0", ::dougleRange) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/annotations/annotationRetentionAnnotation.kt b/backend.native/tests/external/codegen/blackbox/reflection/annotations/annotationRetentionAnnotation.kt new file mode 100644 index 00000000000..c92c6a0cdd0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/annotations/annotationRetentionAnnotation.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +@Retention(AnnotationRetention.RUNTIME) +annotation class Anno + +fun box(): String { + val a = Anno::class.annotations + + if (a.size != 1) return "Fail 1: $a" + val ann = a.single() as? Retention ?: return "Fail 2: ${a.single()}" + assertEquals(AnnotationRetention.RUNTIME, ann.value) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/annotations/annotationsOnJavaMembers.kt b/backend.native/tests/external/codegen/blackbox/reflection/annotations/annotationsOnJavaMembers.kt new file mode 100644 index 00000000000..70c1720d4fc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/annotations/annotationsOnJavaMembers.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +@Anno("J") +public class J { + @Anno("foo") + public static int foo = 42; + + @Anno("bar") + public static void bar() {} + + @Anno("constructor") + public J() {} +} + +// FILE: K.kt + +import kotlin.test.assertEquals + +annotation class Anno(val value: String) + +fun box(): String { + assertEquals("[@Anno(value=J)]", J::class.annotations.toString()) + assertEquals("[@Anno(value=foo)]", J::foo.annotations.toString()) + assertEquals("[@Anno(value=bar)]", J::bar.annotations.toString()) + assertEquals("[@Anno(value=constructor)]", ::J.annotations.toString()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/annotations/findAnnotation.kt b/backend.native/tests/external/codegen/blackbox/reflection/annotations/findAnnotation.kt new file mode 100644 index 00000000000..b008bd65937 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/annotations/findAnnotation.kt @@ -0,0 +1,21 @@ +// IGNORE_BACKEND: JS, NATIVE +// WITH_REFLECT + +import kotlin.reflect.findAnnotation +import kotlin.test.assertNull + +annotation class Yes(val value: String) +annotation class No(val value: String) + +@Yes("OK") +@No("Fail") +class Foo + +class Bar + +fun box(): String { + assertNull(Bar::class.findAnnotation()) + assertNull(Bar::class.findAnnotation()) + + return Foo::class.findAnnotation()?.value ?: "Fail: no annotation" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/annotations/propertyAccessors.kt b/backend.native/tests/external/codegen/blackbox/reflection/annotations/propertyAccessors.kt new file mode 100644 index 00000000000..6817dd64513 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/annotations/propertyAccessors.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +annotation class Get +annotation class Set +annotation class SetParam + +var foo: String + @Get get() = "" + @Set set(@SetParam value) {} + +fun box(): String { + assert(::foo.getter.annotations.single() is Get) + assert(::foo.setter.annotations.single() is Set) + assert(::foo.setter.parameters.single().annotations.single() is SetParam) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/annotations/propertyWithoutBackingField.kt b/backend.native/tests/external/codegen/blackbox/reflection/annotations/propertyWithoutBackingField.kt new file mode 100644 index 00000000000..3a072a5d11e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/annotations/propertyWithoutBackingField.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +annotation class Ann(val value: String) + +@Ann("OK") +val property: String + get() = "" + +fun box(): String { + return (::property.annotations.single() as Ann).value +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/annotations/retentions.kt b/backend.native/tests/external/codegen/blackbox/reflection/annotations/retentions.kt new file mode 100644 index 00000000000..200c0e1aef0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/annotations/retentions.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +@Retention(AnnotationRetention.SOURCE) +annotation class SourceAnno + +@Retention(AnnotationRetention.BINARY) +annotation class BinaryAnno + +@Retention(AnnotationRetention.RUNTIME) +annotation class RuntimeAnno + +@SourceAnno +@BinaryAnno +@RuntimeAnno +fun box(): String { + assertEquals(listOf(RuntimeAnno::class.java), ::box.annotations.map { it.annotationClass.java }) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/annotations/simpleClassAnnotation.kt b/backend.native/tests/external/codegen/blackbox/reflection/annotations/simpleClassAnnotation.kt new file mode 100644 index 00000000000..5da18e3627b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/annotations/simpleClassAnnotation.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +@Retention(AnnotationRetention.RUNTIME) +annotation class Simple(val value: String) + +@Simple("OK") +class A + +fun box(): String { + return (A::class.annotations.single() as Simple).value +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/annotations/simpleConstructorAnnotation.kt b/backend.native/tests/external/codegen/blackbox/reflection/annotations/simpleConstructorAnnotation.kt new file mode 100644 index 00000000000..2d7a036b18c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/annotations/simpleConstructorAnnotation.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +annotation class Primary +annotation class Secondary + +class C @Primary constructor() { + @Secondary + constructor(s: String): this() +} + +fun box(): String { + val ans = C::class.constructors.map { it.annotations.single().annotationClass.java.simpleName }.sorted() + if (ans != listOf("Primary", "Secondary")) return "Fail: $ans" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/annotations/simpleFunAnnotation.kt b/backend.native/tests/external/codegen/blackbox/reflection/annotations/simpleFunAnnotation.kt new file mode 100644 index 00000000000..041cc3f2e6f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/annotations/simpleFunAnnotation.kt @@ -0,0 +1,12 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +@Retention(AnnotationRetention.RUNTIME) +annotation class Simple(val value: String) + +@Simple("OK") +fun box(): String { + return (::box.annotations.single() as Simple).value +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/annotations/simpleParamAnnotation.kt b/backend.native/tests/external/codegen/blackbox/reflection/annotations/simpleParamAnnotation.kt new file mode 100644 index 00000000000..1d45a826b86 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/annotations/simpleParamAnnotation.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +@Retention(AnnotationRetention.RUNTIME) +annotation class Simple(val value: String) + +fun test(@Simple("OK") x: Int) {} + +fun box(): String { + return (::test.parameters.single().annotations.single() as Simple).value +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/annotations/simpleValAnnotation.kt b/backend.native/tests/external/codegen/blackbox/reflection/annotations/simpleValAnnotation.kt new file mode 100644 index 00000000000..216ba88b987 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/annotations/simpleValAnnotation.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +@Retention(AnnotationRetention.RUNTIME) +annotation class Simple(val value: String) + +@property:Simple("OK") +val foo: Int = 0 + +fun box(): String { + return (::foo.annotations.single() as Simple).value +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/bound/companionObjectPropertyAccessors.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/companionObjectPropertyAccessors.kt new file mode 100644 index 00000000000..d3fe286da02 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/companionObjectPropertyAccessors.kt @@ -0,0 +1,53 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.test.assertEquals + +class Host { + companion object { + val x = 1 + var y = 2 + + val xx: Int + get() = x + + var yy: Int + get() = y + set(value) { y = value } + } +} + +val c_x = Host.Companion::x +val c_xx = Host.Companion::xx +val c_y = Host.Companion::y +val c_yy = Host.Companion::yy + +fun box(): String { + assertEquals(1, c_x.getter()) + assertEquals(1, c_x.getter.call()) + assertEquals(1, c_xx.getter()) + assertEquals(1, c_xx.getter.call()) + assertEquals(2, c_y.getter()) + assertEquals(2, c_y.getter.call()) + assertEquals(2, c_yy.getter()) + assertEquals(2, c_yy.getter.call()) + + c_y.setter(10) + assertEquals(10, c_y.getter()) + assertEquals(10, c_yy.getter()) + + c_yy.setter(20) + assertEquals(20, c_y.getter()) + assertEquals(20, c_yy.getter()) + + c_y.setter.call(100) + assertEquals(100, c_yy.getter.call()) + + c_yy.setter.call(200) + assertEquals(200, c_y.getter.call()) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/bound/extensionFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/extensionFunction.kt new file mode 100644 index 00000000000..cd0c53f8123 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/extensionFunction.kt @@ -0,0 +1,12 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* + +fun String.foo(x: String) = this + x +fun String?.bar(x: String) = x + +fun box() = + (""::foo).call("O") + (null::bar).call("K") \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/bound/extensionPropertyAccessors.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/extensionPropertyAccessors.kt new file mode 100644 index 00000000000..449d73d064b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/extensionPropertyAccessors.kt @@ -0,0 +1,45 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.test.assertEquals + +class C(val x: Int, var y: Int) + +val C.xx: Int + get() = x + +var C.yy: Int + get() = y + set(value) { y = value } + + +val c = C(1, 2) + +val c_xx = c::xx +val c_y = c::y +val c_yy = c::yy + +fun box(): String { + assertEquals(1, c_xx.getter()) + assertEquals(1, c_xx.getter.call()) + assertEquals(2, c_yy.getter()) + assertEquals(2, c_yy.getter.call()) + + c_y.setter(10) + assertEquals(10, c_yy.getter()) + + c_yy.setter(20) + assertEquals(20, c_y.getter()) + assertEquals(20, c_yy.getter()) + + c_y.setter.call(100) + assertEquals(100, c_yy.getter.call()) + + c_yy.setter.call(200) + assertEquals(200, c_y.getter.call()) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/bound/innerClassConstructor.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/innerClassConstructor.kt new file mode 100644 index 00000000000..c84e7893a23 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/innerClassConstructor.kt @@ -0,0 +1,16 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +class Outer(val x: String) { + inner class Inner(val y: String) { + fun foo() = x + y + } +} + +fun box(): String { + val innerCtor = Outer("O")::Inner + val inner = innerCtor.call("K") + return inner.foo() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/bound/javaInstanceField.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/javaInstanceField.kt new file mode 100644 index 00000000000..9078fc60f7b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/javaInstanceField.kt @@ -0,0 +1,40 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +// FILE: J.java +public class J { + public final int finalField; + public String mutableField; + + public J(int f, String m) { + this.finalField = f; + this.mutableField = m; + } +} + +// FILE: K.kt +import kotlin.reflect.* +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +fun box(): String { + val j = J(0, "") + + val jf = j::finalField + val jm = j::mutableField + + assertEquals(0, jf.getter()) + assertEquals(0, jf.getter.call()) + assertEquals("", jm.getter()) + assertEquals("", jm.getter.call()) + + jm.setter("1") + assertEquals("1", j.mutableField) + + jm.setter.call("2") + assertEquals("2", j.mutableField) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/bound/javaInstanceMethod.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/javaInstanceMethod.kt new file mode 100644 index 00000000000..062ef47a0d1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/javaInstanceMethod.kt @@ -0,0 +1,35 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +// FILE: J.java +public class J { + private final int param; + + public J(int param) { + this.param = param; + } + + public String foo(int[] arr, Object[] arr2, Integer y) { + return "" + param + arr[0] + arr2[0] + y; + } +} + +// FILE: K.kt +import kotlin.reflect.* +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +fun box(): String { + val f = J(0)::foo + assertEquals( + listOf(IntArray::class.java, Array::class.java, Integer::class.java), + f.parameters.map { it.type.javaType } + ) + assertEquals(String::class.java, f.returnType.javaType) + + assertEquals("01A2", f.call(intArrayOf(1), arrayOf("A"), 2)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/bound/jvmStaticCompanionObjectPropertyAccessors.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/jvmStaticCompanionObjectPropertyAccessors.kt new file mode 100644 index 00000000000..aacb455eeaf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/jvmStaticCompanionObjectPropertyAccessors.kt @@ -0,0 +1,53 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.test.assertEquals + +class Host { + companion object { + @JvmStatic val x = 1 + @JvmStatic var y = 2 + + @JvmStatic val xx: Int + get() = x + + @JvmStatic var yy: Int + get() = y + set(value) { y = value } + } +} + +val c_x = Host.Companion::x +val c_xx = Host.Companion::xx +val c_y = Host.Companion::y +val c_yy = Host.Companion::yy + +fun box(): String { + assertEquals(1, c_x.getter()) + assertEquals(1, c_x.getter.call()) + assertEquals(1, c_xx.getter()) + assertEquals(1, c_xx.getter.call()) + assertEquals(2, c_y.getter()) + assertEquals(2, c_y.getter.call()) + assertEquals(2, c_yy.getter()) + assertEquals(2, c_yy.getter.call()) + + c_y.setter(10) + assertEquals(10, c_y.getter()) + assertEquals(10, c_yy.getter()) + + c_yy.setter(20) + assertEquals(20, c_y.getter()) + assertEquals(20, c_yy.getter()) + + c_y.setter.call(100) + assertEquals(100, c_yy.getter.call()) + + c_yy.setter.call(200) + assertEquals(200, c_y.getter.call()) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/bound/jvmStaticObjectFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/jvmStaticObjectFunction.kt new file mode 100644 index 00000000000..ba51aa848b6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/jvmStaticObjectFunction.kt @@ -0,0 +1,19 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* + +object Host { + @JvmStatic fun foo(x: String) = x +} + +class CompanionOwner { + companion object { + @JvmStatic fun bar(x: String) = x + } +} + +fun box(): String = + (Host::foo).call("O") + (CompanionOwner.Companion::bar).call("K") \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/bound/jvmStaticObjectPropertyAccessors.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/jvmStaticObjectPropertyAccessors.kt new file mode 100644 index 00000000000..9f06a8cb7fa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/jvmStaticObjectPropertyAccessors.kt @@ -0,0 +1,51 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.test.assertEquals + +object Host { + @JvmStatic val x = 1 + @JvmStatic var y = 2 + + @JvmStatic val xx: Int + get() = x + + @JvmStatic var yy: Int + get() = y + set(value) { y = value } +} + +val c_x = Host::x +val c_xx = Host::xx +val c_y = Host::y +val c_yy = Host::yy + +fun box(): String { + assertEquals(1, c_x.getter()) + assertEquals(1, c_x.getter.call()) + assertEquals(1, c_xx.getter()) + assertEquals(1, c_xx.getter.call()) + assertEquals(2, c_y.getter()) + assertEquals(2, c_y.getter.call()) + assertEquals(2, c_yy.getter()) + assertEquals(2, c_yy.getter.call()) + + c_y.setter(10) + assertEquals(10, c_y.getter()) + assertEquals(10, c_yy.getter()) + + c_yy.setter(20) + assertEquals(20, c_y.getter()) + assertEquals(20, c_yy.getter()) + + c_y.setter.call(100) + assertEquals(100, c_yy.getter.call()) + + c_yy.setter.call(200) + assertEquals(200, c_y.getter.call()) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/bound/memberFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/memberFunction.kt new file mode 100644 index 00000000000..08854e132cf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/memberFunction.kt @@ -0,0 +1,14 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* + +class C(val k: String) { + fun foo(s: String) = s + k +} + +fun box(): String = + C("K")::foo.call("O") + diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/bound/memberPropertyAccessors.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/memberPropertyAccessors.kt new file mode 100644 index 00000000000..7b1d165061e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/memberPropertyAccessors.kt @@ -0,0 +1,50 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.test.assertEquals + +class C(val x: Int, var y: Int) { + val xx: Int + get() = x + + var yy: Int + get() = y + set(value) { y = value } +} + +val c = C(1, 2) + +val c_x = c::x +val c_xx = c::xx +val c_y = c::y +val c_yy = c::yy + +fun box(): String { + assertEquals(1, c_x.getter()) + assertEquals(1, c_x.getter.call()) + assertEquals(1, c_xx.getter()) + assertEquals(1, c_xx.getter.call()) + assertEquals(2, c_y.getter()) + assertEquals(2, c_y.getter.call()) + assertEquals(2, c_yy.getter()) + assertEquals(2, c_yy.getter.call()) + + c_y.setter(10) + assertEquals(10, c_y.getter()) + assertEquals(10, c_yy.getter()) + + c_yy.setter(20) + assertEquals(20, c_y.getter()) + assertEquals(20, c_yy.getter()) + + c_y.setter.call(100) + assertEquals(100, c_yy.getter.call()) + + c_yy.setter.call(200) + assertEquals(200, c_y.getter.call()) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/bound/objectFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/objectFunction.kt new file mode 100644 index 00000000000..ba2c7788999 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/objectFunction.kt @@ -0,0 +1,19 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* + +object Host { + fun foo(x: String) = x +} + +class CompanionOwner { + companion object { + fun bar(x: String) = x + } +} + +fun box(): String = + (Host::foo).call("O") + (CompanionOwner.Companion::bar).call("K") \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/bound/objectPropertyAccessors.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/objectPropertyAccessors.kt new file mode 100644 index 00000000000..89062735df3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/bound/objectPropertyAccessors.kt @@ -0,0 +1,51 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.test.assertEquals + +object Host { + val x = 1 + var y = 2 + + val xx: Int + get() = x + + var yy: Int + get() = y + set(value) { y = value } +} + +val c_x = Host::x +val c_xx = Host::xx +val c_y = Host::y +val c_yy = Host::yy + +fun box(): String { + assertEquals(1, c_x.getter()) + assertEquals(1, c_x.getter.call()) + assertEquals(1, c_xx.getter()) + assertEquals(1, c_xx.getter.call()) + assertEquals(2, c_y.getter()) + assertEquals(2, c_y.getter.call()) + assertEquals(2, c_yy.getter()) + assertEquals(2, c_yy.getter.call()) + + c_y.setter(10) + assertEquals(10, c_y.getter()) + assertEquals(10, c_yy.getter()) + + c_yy.setter(20) + assertEquals(20, c_y.getter()) + assertEquals(20, c_yy.getter()) + + c_y.setter.call(100) + assertEquals(100, c_yy.getter.call()) + + c_yy.setter.call(200) + assertEquals(200, c_y.getter.call()) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/callInstanceJavaMethod.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/callInstanceJavaMethod.kt new file mode 100644 index 00000000000..8227fee6f6a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/callInstanceJavaMethod.kt @@ -0,0 +1,35 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public class J { + private final int param; + + public J(int param) { + this.param = param; + } + + public String foo(int[] arr, Object[] arr2, Integer y) { + return "" + param + arr[0] + arr2[0] + y; + } +} + +// FILE: K.kt + +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +fun box(): String { + val f = J::foo + assertEquals( + listOf(J::class.java, IntArray::class.java, Array::class.java, Integer::class.java), + f.parameters.map { it.type.javaType } + ) + assertEquals(String::class.java, f.returnType.javaType) + + assertEquals("01A2", f.call(J(0), intArrayOf(1), arrayOf("A"), 2)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/callPrivateJavaMethod.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/callPrivateJavaMethod.kt new file mode 100644 index 00000000000..1d2c454b234 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/callPrivateJavaMethod.kt @@ -0,0 +1,40 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public class J { + private final String result; + + private J(String result) { + this.result = result; + } + + private String getResult() { + return result; + } +} + +// FILE: K.kt + +import kotlin.reflect.* +import kotlin.reflect.jvm.* +import kotlin.test.* + +fun box(): String { + val c = J::class.constructors.single() + assertFalse(c.isAccessible) + assertFailsWith(IllegalCallableAccessException::class) { c.call("") } + + c.isAccessible = true + assertTrue(c.isAccessible) + val j = c.call("OK") + + val m = J::class.members.single { it.name == "getResult" } + assertFalse(m.isAccessible) + assertFailsWith(IllegalCallableAccessException::class) { m.call(j)!! } + + m.isAccessible = true + return m.call(j) as String +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/callStaticJavaMethod.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/callStaticJavaMethod.kt new file mode 100644 index 00000000000..db9248b3f9a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/callStaticJavaMethod.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public class J { + public static String foo(int x, int[] arr, Object[] arr2) { + return "" + x + arr[0] + arr2[0]; + } +} + +// FILE: K.kt + +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +fun box(): String { + val f = J::foo + assertEquals(listOf(Integer.TYPE, IntArray::class.java, Array::class.java), f.parameters.map { it.type.javaType }) + assertEquals(String::class.java, f.returnType.javaType) + + assertEquals("01A", f.call(0, intArrayOf(1), arrayOf("A"))) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/cannotCallEnumConstructor.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/cannotCallEnumConstructor.kt new file mode 100644 index 00000000000..16d57842386 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/cannotCallEnumConstructor.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.* + +enum class E + +fun box(): String { + try { + val c = E::class.constructors.single() + c.isAccessible = true + c.call() + return "Fail: constructing an enum class should not be allowed" + } + catch (e: Throwable) { + return "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/disallowNullValueForNotNullField.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/disallowNullValueForNotNullField.kt new file mode 100644 index 00000000000..3463a49c85a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/disallowNullValueForNotNullField.kt @@ -0,0 +1,48 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.* + +class A { + private var foo: String = "" +} + +object O { + @JvmStatic + private var bar: String = "" +} + +class CounterTest(t: T) { + private var baz: String? = "" + private var generic: T = t +} + +fun box(): String { + val p = A::class.memberProperties.single() as KMutableProperty1 + p.isAccessible = true + try { + p.setter.call(A(), null) + return "Fail: exception should have been thrown" + } catch (e: IllegalArgumentException) {} + + + val o = O::class.memberProperties.single() as KMutableProperty1 + o.isAccessible = true + try { + o.setter.call(O, null) + return "Fail: exception should have been thrown" + } catch (e: IllegalArgumentException) {} + + + val c = CounterTest::class.memberProperties.single { it.name == "baz" } as KMutableProperty1, String?> + c.isAccessible = true + c.setter.call(CounterTest(""), null) // Should not fail, because CounterTest::baz is nullable + val d = CounterTest::class.memberProperties.single { it.name == "generic" } as KMutableProperty1, String?> + d.isAccessible = true + d.setter.call(CounterTest(""), null) // Also should not fail, because we can't be sure about nullability of 'generic' + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/equalsHashCodeToString.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/equalsHashCodeToString.kt new file mode 100644 index 00000000000..9885d12c3c0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/equalsHashCodeToString.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +class A + +data class D(val s: String) + +fun box(): String { + val a = A() + assert(A::equals.call(a, a)) + assert(!A::equals.call(a, 0)) + assert(A::hashCode.call(a) == A::hashCode.call(a)) + assert(A::toString.call(a).startsWith("A@")) + + assert(D::equals.call(D("foo"), D("foo"))) + assert(!D::equals.call(D("foo"), D("bar"))) + assert(D::hashCode.call(D("foo")) == D::hashCode.call(D("foo"))) + assert(D::toString.call(D("foo")) == "D(s=foo)") + + assert(Int::equals.call(-1, -1)) + assert(Int::hashCode.call(0) != Int::hashCode.call(1)) + assert(Int::toString.call(42) == "42") + + assert(String::equals.call("beer", "beer")) + String::hashCode.call("beer") + + return String::toString.call("OK") +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/exceptionHappened.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/exceptionHappened.kt new file mode 100644 index 00000000000..3cd7d8f73fe --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/exceptionHappened.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FULL_JDK + +import java.lang.reflect.InvocationTargetException + +fun fail(message: String) { + throw AssertionError(message) +} + +fun box(): String { + try { + ::fail.call("OK") + } catch (e: InvocationTargetException) { + return e.getTargetException().message.toString() + } + + return "Fail: no exception was thrown" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/fakeOverride.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/fakeOverride.kt new file mode 100644 index 00000000000..39210c68142 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/fakeOverride.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +open class A { + fun foo() = "OK" +} + +class B : A() + +fun box(): String { + val foo = B::class.members.single { it.name == "foo" } + return foo.call(B()) as String +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/fakeOverrideSubstituted.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/fakeOverrideSubstituted.kt new file mode 100644 index 00000000000..d98c38cd636 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/fakeOverrideSubstituted.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +open class A(val t: T) { + fun foo() = t +} + +class B(s: String) : A(s) + +fun box(): String { + val foo = B::class.members.single { it.name == "foo" } + return foo.call(B("OK")) as String +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/incorrectNumberOfArguments.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/incorrectNumberOfArguments.kt new file mode 100644 index 00000000000..e08b3df5305 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/incorrectNumberOfArguments.kt @@ -0,0 +1,108 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.isAccessible +import kotlin.reflect.KCallable +import kotlin.reflect.KFunction +import kotlin.reflect.KMutableProperty + +var foo: String = "" + +class A(private var bar: String = "") { + fun getBar() = A::bar +} + +object O { + @JvmStatic + private var baz: String = "" + + @JvmStatic + fun getBaz() = (O::class.members.single { it.name == "baz" } as KMutableProperty<*>).apply { isAccessible = true } + + fun getGetBaz() = O::class.members.single { it.name == "getBaz" } as KFunction<*> +} + +fun check(callable: KCallable<*>, vararg args: Any?) { + val expected = callable.parameters.size + val actual = args.size + + if (expected == actual) { + throw AssertionError("Bad test case: expected and actual number of arguments should differ (was $expected vs $actual)") + } + + val expectedExceptionMessage = "Callable expects $expected arguments, but $actual were provided." + + try { + callable.call(*args) + throw AssertionError("Fail: an IllegalArgumentException should have been thrown") + } catch (e: IllegalArgumentException) { + if (e.message != expectedExceptionMessage) { + // This most probably means that we don't check number of passed arguments in reflection + // and the default check from Java reflection yields an IllegalArgumentException, but with a not that helpful message + throw AssertionError("Fail: an exception with an unrecognized message was thrown: \"${e.message}\"" + + "\nExpected message was: $expectedExceptionMessage") + } + } +} + +fun box(): String { + check(::box, null) + check(::box, "") + + check(::A) + check(::A, null, "") + + check(O.getGetBaz()) + check(O.getGetBaz(), null, "") + + + val f = ::foo + check(f, null) + check(f, null, null) + check(f, arrayOf(null)) + check(f, "") + + check(f.getter, null) + check(f.getter, null, null) + check(f.getter, arrayOf(null)) + check(f.getter, "") + + check(f.setter) + check(f.setter, null, null) + check(f.setter, null, "") + + + val b = A().getBar() + + check(b) + check(b, null, null) + check(b, "", "") + + check(b.getter) + check(b.getter, null, null) + check(b.getter, "", "") + + check(b.setter) + check(b.setter, null) + check(b.setter, "") + + + val z = O.getBaz() + + check(z) + check(z, null, null) + check(z, "", "") + + check(z.getter) + check(z.getter, null, null) + check(z.getter, "", "") + + check(z.setter) + check(z.setter, null) + check(z.setter, "") + + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/innerClassConstructor.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/innerClassConstructor.kt new file mode 100644 index 00000000000..60aca8cd5cd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/innerClassConstructor.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +class A { + class Nested(val result: String) + inner class Inner(val result: String) +} + +fun box(): String { + return (A::Nested).call("O").result + (A::Inner).call((::A).call(), "K").result +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/jvmStatic.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/jvmStatic.kt new file mode 100644 index 00000000000..94ea4ffcf51 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/jvmStatic.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +object Obj { + @JvmStatic + fun foo() {} +} + +class C { + companion object { + @JvmStatic + fun bar() {} + } +} + +fun box(): String { + (Obj::class.members.single { it.name == "foo" }).call(Obj) + (C.Companion::class.members.single { it.name == "bar" }).call(C.Companion) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/jvmStaticInObjectIncorrectReceiver.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/jvmStaticInObjectIncorrectReceiver.kt new file mode 100644 index 00000000000..34802763740 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/jvmStaticInObjectIncorrectReceiver.kt @@ -0,0 +1,47 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +object Obj { + @JvmStatic + fun foo(s: String) {} + + @JvmStatic + fun bar() {} + + @JvmStatic + fun sly(obj: Obj) {} + + operator fun get(name: String) = Obj::class.members.single { it.name == name } +} + +fun box(): String { + // This should succeed + (Obj["foo"]).call(Obj, "") + (Obj["bar"]).call(Obj) + (Obj["sly"]).call(Obj, Obj) + + // This shouldn't: first argument should always be Obj + try { + (Obj["foo"]).call(null, "") + return "Fail foo" + } catch (e: IllegalArgumentException) {} + + try { + (Obj["bar"]).call("") + return "Fail bar" + } catch (e: IllegalArgumentException) {} + + try { + (Obj["sly"]).call(Obj) + return "Fail sly 1" + } catch (e: IllegalArgumentException) {} + + try { + (Obj["sly"]).call(null, Obj) + return "Fail sly 2" + } catch (e: IllegalArgumentException) {} + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/localClassMember.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/localClassMember.kt new file mode 100644 index 00000000000..3651f0ed3d9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/localClassMember.kt @@ -0,0 +1,12 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +fun box(): String { + class Local { + fun result(s: String) = s + } + + return Local::result.call(Local(), "OK") +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/memberOfGenericClass.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/memberOfGenericClass.kt new file mode 100644 index 00000000000..e01db003dc0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/memberOfGenericClass.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +var result = "Fail" + +class A { + fun foo(t: T) { + result = t as String + } +} + +fun box(): String { + (A::foo).call(A(), "OK") + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/privateProperty.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/privateProperty.kt new file mode 100644 index 00000000000..f53b15d43d2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/privateProperty.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.* +import kotlin.test.* + +class A(private var result: String) + +fun box(): String { + val a = A("abc") + + val p = A::class.declaredMemberProperties.single() as KMutableProperty1 + p.isAccessible = true + assertEquals("abc", p.call(a)) + assertEquals(Unit, p.setter.call(a, "def")) + assertEquals("def", p.getter.call(a)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/propertyAccessors.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/propertyAccessors.kt new file mode 100644 index 00000000000..3fd5a3d25e0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/propertyAccessors.kt @@ -0,0 +1,52 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.test.assertEquals + +val p0 = 1 +val Int.p1: Int get() = this +class A { + val Int.p2: Int get() = this +} + +var globalCounter = 0 + +var mp0 = 1 + set(value) { globalCounter += value } +var Int.mp1: Int + get() = this + set(value) { globalCounter += value } +class B { + var Int.mp2: Int + get() = this + set(value) { globalCounter += value } +} + + +fun box(): String { + assertEquals(1, (::p0).call()) + assertEquals(1, (::p0).getter.call()) + assertEquals(2, (Int::p1).call(2)) + assertEquals(2, (Int::p1).getter.call(2)) + val p2 = A::class.memberExtensionProperties.single() + assertEquals(3, p2.call(A(), 3)) + assertEquals(3, p2.getter.call(A(), 3)) + + assertEquals(1, (::mp0).call()) + assertEquals(1, (::mp0).getter.call()) + assertEquals(2, (Int::mp1).call(2)) + assertEquals(2, (Int::mp1).getter.call(2)) + val mp2 = B::class.memberExtensionProperties.single() as KMutableProperty2 + assertEquals(3, mp2.call(B(), 3)) + assertEquals(3, mp2.getter.call(B(), 3)) + + assertEquals(Unit, (::mp0).setter.call(1)) + assertEquals(Unit, (Int::mp1).setter.call(0, 3)) + assertEquals(Unit, mp2.setter.call(B(), 0, 5)) + if (globalCounter != 9) return "Fail: $globalCounter" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/propertyGetterAndGetFunctionDifferentReturnType.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/propertyGetterAndGetFunctionDifferentReturnType.kt new file mode 100644 index 00000000000..3e8a009e650 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/propertyGetterAndGetFunctionDifferentReturnType.kt @@ -0,0 +1,12 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +data class Foo(val id: String) { + fun getId() = -42 // Fail +} + +fun box(): String { + return Foo::id.call(Foo("OK")) +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/returnUnit.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/returnUnit.kt new file mode 100644 index 00000000000..d7bc48f26c0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/returnUnit.kt @@ -0,0 +1,29 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +fun foo() {} + +class A { + fun bar() {} +} + +object O { + @JvmStatic fun baz() {} +} + +fun nullableUnit(unit: Boolean): Unit? = if (unit) Unit else null + +fun box(): String { + assertEquals(Unit, ::foo.call()) + assertEquals(Unit, A::bar.call(A())) + assertEquals(Unit, O::class.members.single { it.name == "baz" }.call(O)) + + assertEquals(Unit, (::nullableUnit).call(true)) + assertEquals(null, (::nullableUnit).call(false)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/simpleConstructor.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/simpleConstructor.kt new file mode 100644 index 00000000000..6a71248b113 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/simpleConstructor.kt @@ -0,0 +1,11 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +class A(val result: String) + +fun box(): String { + val a = (::A).call("OK") + return a.result +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/simpleMemberFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/simpleMemberFunction.kt new file mode 100644 index 00000000000..52edb5a0b8e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/simpleMemberFunction.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +class A { + fun foo(x: Int, y: Int) = x + y +} + +fun box(): String { + val x = (A::foo).call(A(), 42, 239) + if (x != 281) return "Fail: $x" + + try { + (A::foo).call() + return "Fail: no exception" + } + catch (e: Exception) {} + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/call/simpleTopLevelFunctions.kt b/backend.native/tests/external/codegen/blackbox/reflection/call/simpleTopLevelFunctions.kt new file mode 100644 index 00000000000..ea29b5e704d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/call/simpleTopLevelFunctions.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +fun String.foo(): Int = length + +var state = "Fail" + +fun bar(result: String) { + state = result +} + +fun box(): String { + val f = (String::foo).call("abc") + if (f != 3) return "Fail: $f" + + try { + (String::foo).call() + return "Fail: IllegalArgumentException should have been thrown" + } + catch (e: IllegalArgumentException) {} + + try { + (String::foo).call(42) + return "Fail: IllegalArgumentException should have been thrown" + } + catch (e: IllegalArgumentException) {} + + (::bar).call("OK") + return state +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/boundExtensionFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/boundExtensionFunction.kt new file mode 100644 index 00000000000..906dcb9d4fb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/boundExtensionFunction.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +fun String.extFun(k: String, s: String = "") = this + k + s + +fun box(): String { + val sExtFun = "O"::extFun + return sExtFun.callBy(mapOf(sExtFun.parameters[0] to "K")) +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/boundExtensionPropertyAcessor.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/boundExtensionPropertyAcessor.kt new file mode 100644 index 00000000000..1cd1409ca0d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/boundExtensionPropertyAcessor.kt @@ -0,0 +1,12 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +val String.plusK: String + get() = this + "K" + +fun box(): String = + ("O"::plusK).getter.callBy(mapOf()) \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/boundJvmStaticInObject.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/boundJvmStaticInObject.kt new file mode 100644 index 00000000000..47ffa196b2c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/boundJvmStaticInObject.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +object Host { + @JvmStatic fun concat(s1: String, s2: String, s3: String = "K", s4: String = "x") = + s1 + s2 + s3 + s4 +} + +fun box(): String { + val concat = Host::concat + val concatParams = concat.parameters + return concat.callBy(mapOf( + concatParams[0] to "", + concatParams[1] to "O", + concatParams[3] to "" + )) +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/companionObject.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/companionObject.kt new file mode 100644 index 00000000000..5f7e2e56051 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/companionObject.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +class C { + companion object { + fun foo(a: String, b: String = "b") = a + b + } +} + +fun box(): String { + val f = C.Companion::class.members.single { it.name == "foo" } + + // Any object method currently requires the object instance passed + try { + f.callBy(mapOf( + f.parameters.single { it.name == "a" } to "a" + )) + return "Fail: IllegalArgumentException should have been thrown" + } + catch (e: IllegalArgumentException) { + // OK + } + + assertEquals("ab", f.callBy(mapOf( + f.parameters.first() to C, + f.parameters.single { it.name == "a" } to "a" + ))) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/defaultAndNonDefaultIntertwined.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/defaultAndNonDefaultIntertwined.kt new file mode 100644 index 00000000000..c75b0793f1b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/defaultAndNonDefaultIntertwined.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +fun foo(a: String, b: String = "b", c: String, d: String = "d", e: String) = + a + b + c + d + e + +fun box(): String { + val p = ::foo.parameters + assertEquals("abcde", ::foo.callBy(mapOf( + p[0] to "a", + p[2] to "c", + p[4] to "e" + ))) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/extensionFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/extensionFunction.kt new file mode 100644 index 00000000000..b444a3c9358 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/extensionFunction.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +fun String.sum(other: String = "b") = this + other + +fun box(): String { + val f = String::sum + assertEquals("ab", f.callBy(mapOf(f.parameters.first() to "a"))) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/jvmStaticInCompanionObject.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/jvmStaticInCompanionObject.kt new file mode 100644 index 00000000000..f4c70d27d38 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/jvmStaticInCompanionObject.kt @@ -0,0 +1,37 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +// KT-12915 IAE on callBy of JvmStatic function with default arguments + +import kotlin.test.assertEquals + +class C { + companion object { + @JvmStatic + fun foo(a: String, b: String = "b") = a + b + } +} + +fun box(): String { + val f = C.Companion::class.members.single { it.name == "foo" } + + // Any object method currently requires the object instance passed + try { + f.callBy(mapOf( + f.parameters.single { it.name == "a" } to "a" + )) + return "Fail: IllegalArgumentException should have been thrown" + } + catch (e: IllegalArgumentException) { + // OK + } + + assertEquals("ab", f.callBy(mapOf( + f.parameters.first() to C, + f.parameters.single { it.name == "a" } to "a" + ))) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/jvmStaticInObject.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/jvmStaticInObject.kt new file mode 100644 index 00000000000..83a1120e2c8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/jvmStaticInObject.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +object Obj { + @JvmStatic + fun foo(a: String, b: String = "b") = a + b +} + +fun box(): String { + val f = Obj::class.members.single { it.name == "foo" } + + // Any object method currently requires the object instance passed + try { + f.callBy(mapOf( + f.parameters.single { it.name == "a" } to "a" + )) + return "Fail: IllegalArgumentException should have been thrown" + } + catch (e: IllegalArgumentException) { + // OK + } + + assertEquals("ab", f.callBy(mapOf( + f.parameters.first() to Obj, + f.parameters.single { it.name == "a" } to "a" + ))) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/manyArgumentsOnlyOneDefault.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/manyArgumentsOnlyOneDefault.kt new file mode 100644 index 00000000000..8f9a92519fd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/manyArgumentsOnlyOneDefault.kt @@ -0,0 +1,102 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +// Generate: +// (1..70).map { " p${"%02d".format(it)}: Int," }.joinToString("\n") + +class A { + fun foo( + p01: Int, + p02: Int, + p03: Int, + p04: Int, + p05: Int, + p06: Int, + p07: Int, + p08: Int, + p09: Int, + p10: Int, + p11: Int, + p12: Int, + p13: Int, + p14: Int, + p15: Int, + p16: Int, + p17: Int, + p18: Int, + p19: Int, + p20: Int, + p21: Int, + p22: Int, + p23: Int, + p24: Int, + p25: Int, + p26: Int, + p27: Int, + p28: Int, + p29: Int, + p30: Int, + p31: Int, + p32: Int, + p33: Int, + p34: Int, + p35: Int, + p36: Int, + p37: Int, + p38: Int, + p39: Int, + p40: Int, + p41: Int, + p42: Int = 239, + p43: Int, + p44: Int, + p45: Int, + p46: Int, + p47: Int, + p48: Int, + p49: Int, + p50: Int, + p51: Int, + p52: Int, + p53: Int, + p54: Int, + p55: Int, + p56: Int, + p57: Int, + p58: Int, + p59: Int, + p60: Int, + p61: Int, + p62: Int, + p63: Int, + p64: Int, + p65: Int, + p66: Int, + p67: Int, + p68: Int, + p69: Int, + p70: Int + ) { + assertEquals(1, p01) + assertEquals(41, p41) + assertEquals(239, p42) + assertEquals(43, p43) + assertEquals(70, p70) + } +} + +fun box(): String { + val f = A::class.members.single { it.name == "foo" } + val parameters = f.parameters + + f.callBy(mapOf( + parameters.first() to A(), + *((1..41) + (43..70)).map { i -> parameters[i] to i }.toTypedArray() + )) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/manyMaskArguments.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/manyMaskArguments.kt new file mode 100644 index 00000000000..002da4ac148 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/manyMaskArguments.kt @@ -0,0 +1,100 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +// Generate: +// (1..70).map { " p${"%02d".format(it)}: Int = $it," }.joinToString("\n") + +class A { + fun foo( + p01: Int = 1, + p02: Int = 2, + p03: Int = 3, + p04: Int = 4, + p05: Int = 5, + p06: Int = 6, + p07: Int = 7, + p08: Int = 8, + p09: Int = 9, + p10: Int = 10, + p11: Int = 11, + p12: Int = 12, + p13: Int = 13, + p14: Int = 14, + p15: Int = 15, + p16: Int = 16, + p17: Int = 17, + p18: Int = 18, + p19: Int = 19, + p20: Int = 20, + p21: Int = 21, + p22: Int = 22, + p23: Int = 23, + p24: Int = 24, + p25: Int = 25, + p26: Int = 26, + p27: Int = 27, + p28: Int = 28, + p29: Int = 29, + p30: Int = 30, + p31: Int = 31, + p32: Int = 32, + p33: Int = 33, + p34: Int = 34, + p35: Int = 35, + p36: Int = 36, + p37: Int = 37, + p38: Int = 38, + p39: Int = 39, + p40: Int = 40, + p41: Int = 41, + p42: Int, + p43: Int = 43, + p44: Int = 44, + p45: Int = 45, + p46: Int = 46, + p47: Int = 47, + p48: Int = 48, + p49: Int = 49, + p50: Int = 50, + p51: Int = 51, + p52: Int = 52, + p53: Int = 53, + p54: Int = 54, + p55: Int = 55, + p56: Int = 56, + p57: Int = 57, + p58: Int = 58, + p59: Int = 59, + p60: Int = 60, + p61: Int = 61, + p62: Int = 62, + p63: Int = 63, + p64: Int = 64, + p65: Int = 65, + p66: Int = 66, + p67: Int = 67, + p68: Int = 68, + p69: Int = 69, + p70: Int = 70 + ) { + assertEquals(1, p01) + assertEquals(41, p41) + assertEquals(239, p42) + assertEquals(43, p43) + assertEquals(70, p70) + } +} + +fun box(): String { + val f = A::class.members.single { it.name == "foo" } + val parameters = f.parameters + f.callBy(mapOf( + parameters.first() to A(), + parameters.single { it.name == "p42" } to 239 + )) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/nonDefaultParameterOmitted.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/nonDefaultParameterOmitted.kt new file mode 100644 index 00000000000..fb25dac5f87 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/nonDefaultParameterOmitted.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +fun foo(x: Int, y: Int = 2) = x + y + +fun box(): String { + try { + ::foo.callBy(mapOf()) + return "Fail: IllegalArgumentException must have been thrown" + } + catch (e: IllegalArgumentException) { + // OK + } + + try { + ::foo.callBy(mapOf(::foo.parameters.last() to 1)) + return "Fail: IllegalArgumentException must have been thrown" + } + catch (e: IllegalArgumentException) { + // OK + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/nullValue.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/nullValue.kt new file mode 100644 index 00000000000..289b8a26de6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/nullValue.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertNull + +fun foo(x: String? = "Fail") { + assertNull(x) +} + +fun box(): String { + ::foo.callBy(mapOf(::foo.parameters.single() to null)) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/ordinaryMethodIsInvokedWhenNoDefaultValuesAreUsed.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/ordinaryMethodIsInvokedWhenNoDefaultValuesAreUsed.kt new file mode 100644 index 00000000000..71468dcc19f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/ordinaryMethodIsInvokedWhenNoDefaultValuesAreUsed.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FULL_JDK + +import kotlin.test.assertEquals + +fun foo(result: String = "foo") { + assertEquals("box", result) + + // Check that this function was invoked directly and not through the "foo$default", i.e. there's no "foo$default" in the stack trace + val st = Thread.currentThread().stackTrace + for (i in 0..5) { + if ("foo\$default" in st[i].methodName) { + throw AssertionError("KCallable.call should invoke the method directly if all arguments are provided") + } + } +} + +fun box(): String { + ::foo.callBy(mapOf(::foo.parameters.single() to "box")) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/primitiveDefaultValues.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/primitiveDefaultValues.kt new file mode 100644 index 00000000000..9e1ba89d17d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/primitiveDefaultValues.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +fun primitives( + boolean: Boolean = true, + character: Char = 'z', + byte: Byte = 5.toByte(), + short: Short = (-5).toShort(), + int: Int = 2000000000, + float: Float = -2.72f, + long: Long = 1000000000000000000L, + double: Double = 3.14159265359 +) { + assertEquals(true, boolean) + assertEquals('z', character) + assertEquals(5.toByte(), byte) + assertEquals((-5).toShort(), short) + assertEquals(2000000000, int) + assertEquals(-2.72f, float) + assertEquals(1000000000000000000L, long) + assertEquals(3.14159265359, double) +} + +fun box(): String { + ::primitives.callBy(emptyMap()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/privateMemberFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/privateMemberFunction.kt new file mode 100644 index 00000000000..5c089543230 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/privateMemberFunction.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.IllegalCallableAccessException +import kotlin.reflect.jvm.isAccessible + +class A { + private fun foo(default: Any? = this) { + } + + fun f() = A::foo +} + +fun box(): String { + val a = A() + val f = a.f() + + try { + f.callBy(mapOf(f.parameters.first() to a)) + return "Fail: IllegalCallableAccessException should have been thrown" + } + catch (e: IllegalCallableAccessException) { + // OK + } + + f.isAccessible = true + f.callBy(mapOf(f.parameters.first() to a)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/simpleConstructor.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/simpleConstructor.kt new file mode 100644 index 00000000000..e8739d2b0ec --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/simpleConstructor.kt @@ -0,0 +1,8 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +class A(val result: String = "OK") + +fun box(): String = ::A.callBy(mapOf()).result diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/simpleMemberFunciton.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/simpleMemberFunciton.kt new file mode 100644 index 00000000000..afef083b80a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/simpleMemberFunciton.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +class A(val result: String = "OK") { + fun foo(x: Int = 42): String { + assert(x == 42) { x } + return result + } +} + +fun box(): String = A::foo.callBy(mapOf(A::foo.parameters.first() to A())) diff --git a/backend.native/tests/external/codegen/blackbox/reflection/callBy/simpleTopLevelFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/callBy/simpleTopLevelFunction.kt new file mode 100644 index 00000000000..4d7e1bab754 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/callBy/simpleTopLevelFunction.kt @@ -0,0 +1,8 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +fun foo(result: String = "OK") = result + +fun box(): String = ::foo.callBy(mapOf()) diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/annotationClassLiteral.kt b/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/annotationClassLiteral.kt new file mode 100644 index 00000000000..28d5dd9a046 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/annotationClassLiteral.kt @@ -0,0 +1,12 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +fun box(): String { + assertEquals("Deprecated", Deprecated::class.simpleName) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/arrays.kt b/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/arrays.kt new file mode 100644 index 00000000000..89f972009a0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/arrays.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.* +import kotlin.reflect.KClass + +fun box(): String { + val any = Array::class + val string = Array::class + + assertNotEquals>(any, string) + assertNotEquals>(any.java, string.java) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/builtinClassLiterals.kt b/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/builtinClassLiterals.kt new file mode 100644 index 00000000000..84579d3b5e2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/builtinClassLiterals.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +fun box(): String { + assertEquals("Any", Any::class.simpleName) + assertEquals("String", String::class.simpleName) + assertEquals("CharSequence", CharSequence::class.simpleName) + assertEquals("Number", Number::class.simpleName) + assertEquals("Int", Int::class.simpleName) + assertEquals("Long", Long::class.simpleName) + + assertEquals("Array", Array::class.simpleName) + assertEquals("Array", Array::class.simpleName) + + assertEquals("Companion", Int.Companion::class.simpleName) + assertEquals("Companion", Double.Companion::class.simpleName) + assertEquals("Companion", Char.Companion::class.simpleName) + + assertEquals("IntRange", IntRange::class.simpleName) + + assertEquals("List", List::class.simpleName) + + // TODO: this is wrong but should be fixed + assertEquals("List", MutableList::class.simpleName) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/genericArrays.kt b/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/genericArrays.kt new file mode 100644 index 00000000000..60ad96ec239 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/genericArrays.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.* +import kotlin.reflect.* +import kotlin.reflect.jvm.* + +class Klass + +inline fun arrayClass(): KClass> = Array::class + +fun box(): String { + assertEquals("Array", arrayClass().simpleName) + assertEquals("Array", arrayClass().simpleName) + assertEquals("Array", arrayClass>().simpleName) + assertEquals("Array", arrayClass().simpleName) + assertEquals("Array", arrayClass().simpleName) + assertEquals("Array", arrayClass>().simpleName) + assertEquals("Array", arrayClass>().simpleName) + + // Should not be that way. Fix this test when backend is fixed. + assertEquals("[Ljava.lang.Object;", arrayClass().jvmName) + assertEquals("[Ljava.lang.Object;", arrayClass().jvmName) + assertEquals("[Ljava.lang.Object;", arrayClass>().jvmName) + assertEquals("[Ljava.lang.Object;", arrayClass().jvmName) + assertEquals("[Ljava.lang.Object;", arrayClass().jvmName) + assertEquals("[Ljava.lang.Object;", arrayClass>().jvmName) + assertEquals("[Ljava.lang.Object;", arrayClass>().jvmName) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/genericClass.kt b/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/genericClass.kt new file mode 100644 index 00000000000..c80289cb43b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/genericClass.kt @@ -0,0 +1,11 @@ +// WITH_REFLECT + +import kotlin.test.assertEquals + +class Generic + +fun box(): String { + val g = Generic::class + assertEquals("Generic", g.simpleName) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/reifiedTypeClassLiteral.kt b/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/reifiedTypeClassLiteral.kt new file mode 100644 index 00000000000..634efba9520 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/reifiedTypeClassLiteral.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.* + +class Klass +class Other + +inline fun simpleName(): String = + T::class.simpleName!! + +inline fun twoReifiedParams(): String = + "${T1::class.simpleName!!}, ${T2::class.simpleName!!}" + +inline fun myJavaClass(): Class = + T::class.java + +fun box(): String { + assertEquals("Klass", simpleName()) + assertEquals("Int", simpleName()) + assertEquals("Array", simpleName>()) + assertEquals("Error", simpleName()) + assertEquals("Klass, Other", twoReifiedParams()) + + assertEquals(String::class.java, myJavaClass()) + assertEquals(IntArray::class.java, myJavaClass()) + assertEquals(Klass::class.java, myJavaClass()) + assertEquals(Error::class.java, myJavaClass()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/simpleClassLiteral.kt b/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/simpleClassLiteral.kt new file mode 100644 index 00000000000..2749cd70720 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classLiterals/simpleClassLiteral.kt @@ -0,0 +1,8 @@ +// WITH_REFLECT + +class A + +fun box(): String { + val klass = A::class + return if (klass.toString() == "class A") "OK" else "Fail: $klass" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classes/classSimpleName.kt b/backend.native/tests/external/codegen/blackbox/reflection/classes/classSimpleName.kt new file mode 100644 index 00000000000..fc355592cfa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classes/classSimpleName.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +class Klass + +fun box(): String { + assertEquals("Klass", Klass::class.simpleName) + assertEquals("Date", java.util.Date::class.simpleName) + assertEquals("ObjectRef", kotlin.jvm.internal.Ref.ObjectRef::class.simpleName) + assertEquals("Void", java.lang.Void::class.simpleName) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classes/companionObject.kt b/backend.native/tests/external/codegen/blackbox/reflection/classes/companionObject.kt new file mode 100644 index 00000000000..a3f3b46210f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classes/companionObject.kt @@ -0,0 +1,51 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.test.* + +class A { + companion object C +} + +enum class E { + ENTRY; + companion object {} +} + +fun box(): String { + val obj = A::class.companionObject + assertNotNull(obj) + assertEquals("C", obj!!.simpleName) + + assertEquals(A.C, A::class.companionObjectInstance) + assertEquals(A.C, obj.objectInstance) + + assertNull(A.C::class.companionObject) + assertNull(A.C::class.companionObjectInstance) + + assertEquals(E.Companion, E::class.companionObjectInstance) + + assertEquals(String, String::class.companionObjectInstance) + assertEquals(String, String.Companion::class.objectInstance) + assertEquals(Enum, Enum::class.companionObjectInstance) + assertEquals(Enum, Enum.Companion::class.objectInstance) + assertEquals(Double, Double::class.companionObjectInstance) + assertEquals(Double, Double.Companion::class.objectInstance) + assertEquals(Float, Float::class.companionObjectInstance) + assertEquals(Float, Float.Companion::class.objectInstance) + assertEquals(Int, Int::class.companionObjectInstance) + assertEquals(Int, Int.Companion::class.objectInstance) + assertEquals(Long, Long::class.companionObjectInstance) + assertEquals(Long, Long.Companion::class.objectInstance) + assertEquals(Short, Short::class.companionObjectInstance) + assertEquals(Short, Short.Companion::class.objectInstance) + assertEquals(Byte, Byte::class.companionObjectInstance) + assertEquals(Byte, Byte.Companion::class.objectInstance) + assertEquals(Char, Char::class.companionObjectInstance) + assertEquals(Char, Char.Companion::class.objectInstance) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classes/createInstance.kt b/backend.native/tests/external/codegen/blackbox/reflection/classes/createInstance.kt new file mode 100644 index 00000000000..439de318d50 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classes/createInstance.kt @@ -0,0 +1,76 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.full.createInstance +import kotlin.test.assertTrue +import kotlin.test.fail + +// Good classes + +class Simple +class PrimaryWithDefaults(val d1: String = "d1", val d2: Int = 2) +class Secondary(val s: String) { + constructor() : this("s") +} +class SecondaryWithDefaults(val s: String) { + constructor(x: Int = 0) : this(x.toString()) +} +class SecondaryWithDefaultsNoPrimary { + constructor(x: Int) {} + constructor(s: String = "") {} +} + +// Bad classes + +class NoNoArgConstructor(val s: String) { + constructor(x: Int) : this(x.toString()) +} +class NoArgAndDefault() { + constructor(x: Int = 0) : this() +} +class DefaultPrimaryAndDefaultSecondary(val s: String = "") { + constructor(x: Int = 0) : this(x.toString()) +} +class SeveralDefaultSecondaries { + constructor(x: Int = 0) {} + constructor(s: String = "") {} + constructor(d: Double = 3.14) {} +} +class PrivateConstructor private constructor() +object Object + +// ----------- + +inline fun test() { + val instance = T::class.createInstance() + assertTrue(instance is T) +} + +inline fun testFail() { + try { + T::class.createInstance() + fail("createInstance should have failed on ${T::class}") + } catch (e: Exception) { + // OK + } +} + +fun box(): String { + test() + test() + test() + test() + test() + test() + + testFail() + testFail() + testFail() + testFail() + testFail() + testFail() + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classes/declaredMembers.kt b/backend.native/tests/external/codegen/blackbox/reflection/classes/declaredMembers.kt new file mode 100644 index 00000000000..5902aafbae9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classes/declaredMembers.kt @@ -0,0 +1,53 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: I.java + +public class I { + public static void publicStaticI() {} + public void publicMemberI() {} + private static void privateStaticI() {} + private void privateMemberI() {} +} + +// FILE: J.java + +public class J extends I { + public static void publicStaticJ() {} + public void publicMemberJ() {} + private static void privateStaticJ() {} + private void privateMemberJ() {} +} + +// FILE: K.kt + +import kotlin.reflect.full.declaredMembers +import kotlin.test.assertEquals + +open class K : J() { + open fun publicKFun() {} + private fun privateKFun() {} + var publicKProp = Unit + private val privateKProp = Unit +} + +class L : K() { + fun publicLFun() {} + private fun privateLFun() {} + val publicLProp = Unit + private var privateLProp = Unit +} + +inline fun test(vararg names: String) { + assertEquals(names.toSet(), T::class.declaredMembers.map { it.name }.toSet()) +} + +fun box(): String { + test("publicStaticI", "publicMemberI", "privateStaticI", "privateMemberI") + test("publicStaticJ", "publicMemberJ", "privateStaticJ", "privateMemberJ") + test("publicKFun", "privateKFun", "publicKProp", "privateKProp") + test("publicLFun", "privateLFun", "publicLProp", "privateLProp") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classes/jvmName.kt b/backend.native/tests/external/codegen/blackbox/reflection/classes/jvmName.kt new file mode 100644 index 00000000000..36f86129b84 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classes/jvmName.kt @@ -0,0 +1,45 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals +import kotlin.test.assertTrue +import kotlin.reflect.jvm.jvmName + +class Klass { + class Nested + companion object +} + +fun box(): String { + assertEquals("Klass", Klass::class.jvmName) + assertEquals("Klass\$Nested", Klass.Nested::class.jvmName) + assertEquals("Klass\$Companion", Klass.Companion::class.jvmName) + + assertEquals("java.lang.Object", Any::class.jvmName) + assertEquals("int", Int::class.jvmName) + assertEquals("[I", IntArray::class.jvmName) + assertEquals("java.util.List", List::class.jvmName) + assertEquals("java.util.List", MutableList::class.jvmName) + assertEquals("java.lang.String", String::class.jvmName) + assertEquals("java.lang.String", java.lang.String::class.jvmName) + + assertEquals("[Ljava.lang.Object;", Array::class.jvmName) + assertEquals("[Ljava.lang.Integer;", Array::class.jvmName) + assertEquals("[[Ljava.lang.String;", Array>::class.jvmName) + + assertEquals("java.util.Date", java.util.Date::class.jvmName) + assertEquals("kotlin.jvm.internal.Ref\$ObjectRef", kotlin.jvm.internal.Ref.ObjectRef::class.jvmName) + assertEquals("java.lang.Void", java.lang.Void::class.jvmName) + + class Local + val l = Local::class.jvmName + assertTrue(l != null && l.startsWith("JvmNameKt\$") && "\$box\$" in l && l.endsWith("\$Local")) + + val obj = object {} + val o = obj.javaClass.kotlin.jvmName + assertTrue(o != null && o.startsWith("JvmNameKt\$") && "\$box\$" in o && o.endsWith("\$1")) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classes/localClassSimpleName.kt b/backend.native/tests/external/codegen/blackbox/reflection/classes/localClassSimpleName.kt new file mode 100644 index 00000000000..027c49b58a8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classes/localClassSimpleName.kt @@ -0,0 +1,41 @@ +// WITH_REFLECT + +import kotlin.reflect.KClass +import kotlin.test.assertEquals + +fun check(klass: KClass<*>, expectedName: String) { + assertEquals(expectedName, klass.simpleName) +} + +fun localInMethod() { + fun localInMethod(unused: Any?) { + class Local + check(Local::class, "Local") + + class `Local$With$Dollars` + check(`Local$With$Dollars`::class, "Local\$With\$Dollars") + } + localInMethod(null) + + class Local + check(Local::class, "Local") + + class `Local$With$Dollars` + check(`Local$With$Dollars`::class, "Local\$With\$Dollars") +} + +class LocalInConstructor { + init { + class Local + check(Local::class, "Local") + + class `Local$With$Dollars` + check(`Local$With$Dollars`::class, "Local\$With\$Dollars") + } +} + +fun box(): String { + localInMethod() + LocalInConstructor() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classes/nestedClasses.kt b/backend.native/tests/external/codegen/blackbox/reflection/classes/nestedClasses.kt new file mode 100644 index 00000000000..ee73af820f8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classes/nestedClasses.kt @@ -0,0 +1,62 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FULL_JDK + +import kotlin.reflect.KClass +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +class A { + companion object {} + inner class Inner + class Nested + private class PrivateNested +} + +fun nestedNames(c: KClass<*>) = c.nestedClasses.map { it.simpleName ?: throw AssertionError("Unnamed class: ${it.java}") }.sorted() + +fun box(): String { + // Kotlin class without nested classes + assertEquals(emptyList(), nestedNames(A.Inner::class)) + // Kotlin class with nested classes + assertEquals(listOf("Companion", "Inner", "Nested", "PrivateNested"), nestedNames(A::class)) + + // Java class without nested classes + assertEquals(emptyList(), nestedNames(Error::class)) + // Java class with nested classes + assertEquals(listOf("State", "UncaughtExceptionHandler"), nestedNames(Thread::class)) + + // Built-ins + assertEquals(emptyList(), nestedNames(Array::class)) + assertEquals(emptyList(), nestedNames(CharSequence::class)) + assertEquals(listOf("Companion"), nestedNames(String::class)) + + assertEquals(emptyList(), nestedNames(Collection::class)) + assertEquals(emptyList(), nestedNames(MutableCollection::class)) + assertEquals(emptyList(), nestedNames(List::class)) + assertEquals(emptyList(), nestedNames(MutableList::class)) + assertEquals(listOf("Entry"), nestedNames(Map::class)) + assertEquals(emptyList(), nestedNames(Map.Entry::class)) + assertEquals(emptyList(), nestedNames(MutableMap.MutableEntry::class)) + + // TODO: should be MutableEntry. Currently we do not distinguish between Map and MutableMap. + assertEquals(listOf("Entry"), nestedNames(MutableMap::class)) + + // Primitives + for (primitive in listOf(Byte::class, Double::class, Float::class, Int::class, Long::class, Short::class, Char::class)) { + assertEquals(listOf("Companion"), nestedNames(primitive)) + } + assertEquals(emptyList(), nestedNames(Boolean::class)) + + // Primitive arrays + for (primitiveArray in listOf( + ByteArray::class, DoubleArray::class, FloatArray::class, IntArray::class, + LongArray::class, ShortArray::class, CharArray::class, BooleanArray::class + )) { + assertEquals(emptyList(), nestedNames(primitiveArray)) + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classes/nestedClassesJava.kt b/backend.native/tests/external/codegen/blackbox/reflection/classes/nestedClassesJava.kt new file mode 100644 index 00000000000..1758075a74b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classes/nestedClassesJava.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public class J { + public class Inner {} + + public static class Nested {} + + private static class PrivateNested {} + + // This anonymous class should not appear in 'nestedClasses' + private final Object o = new Object() {}; +} + +// FILE: K.kt + +import kotlin.test.assertEquals + +fun box(): String { + assertEquals(listOf("Inner", "Nested", "PrivateNested"), J::class.nestedClasses.map { it.simpleName!! }.sorted()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classes/objectInstance.kt b/backend.native/tests/external/codegen/blackbox/reflection/classes/objectInstance.kt new file mode 100644 index 00000000000..91b4da09e92 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classes/objectInstance.kt @@ -0,0 +1,36 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +object Obj { + fun foo() = 1 +} + +class A { + companion object { + fun foo() = 2 + } +} + +class B { + companion object Factory { + fun foo() = 3 + } +} + +class C + +fun box(): String { + assertEquals(1, Obj::class.objectInstance!!.foo()) + assertEquals(2, A.Companion::class.objectInstance!!.foo()) + assertEquals(3, B.Factory::class.objectInstance!!.foo()) + + assertEquals(null, C::class.objectInstance) + assertEquals(null, String::class.objectInstance) + assertEquals(Unit, Unit::class.objectInstance) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classes/primitiveKClassEquality.kt b/backend.native/tests/external/codegen/blackbox/reflection/classes/primitiveKClassEquality.kt new file mode 100644 index 00000000000..23f86775d68 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classes/primitiveKClassEquality.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals +import kotlin.test.assertFalse + +fun box(): String { + val x = Int::class.javaPrimitiveType!!.kotlin + val y = Int::class.javaObjectType.kotlin + + assertEquals(x, y) + assertEquals(x.hashCode(), y.hashCode()) + assertFalse(x === y) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classes/qualifiedName.kt b/backend.native/tests/external/codegen/blackbox/reflection/classes/qualifiedName.kt new file mode 100644 index 00000000000..824214142a5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classes/qualifiedName.kt @@ -0,0 +1,41 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +class Klass { + class Nested + companion object +} + +fun box(): String { + assertEquals("Klass", Klass::class.qualifiedName) + assertEquals("Klass.Nested", Klass.Nested::class.qualifiedName) + assertEquals("Klass.Companion", Klass.Companion::class.qualifiedName) + + assertEquals("kotlin.Any", Any::class.qualifiedName) + assertEquals("kotlin.Int", Int::class.qualifiedName) + assertEquals("kotlin.Int.Companion", Int.Companion::class.qualifiedName) + assertEquals("kotlin.IntArray", IntArray::class.qualifiedName) + assertEquals("kotlin.collections.List", List::class.qualifiedName) + assertEquals("kotlin.String", String::class.qualifiedName) + assertEquals("kotlin.String", java.lang.String::class.qualifiedName) + + assertEquals("kotlin.Array", Array::class.qualifiedName) + assertEquals("kotlin.Array", Array::class.qualifiedName) + assertEquals("kotlin.Array", Array>::class.qualifiedName) + + assertEquals("java.util.Date", java.util.Date::class.qualifiedName) + assertEquals("kotlin.jvm.internal.Ref.ObjectRef", kotlin.jvm.internal.Ref.ObjectRef::class.qualifiedName) + assertEquals("java.lang.Void", java.lang.Void::class.qualifiedName) + + class Local + assertEquals(null, Local::class.qualifiedName) + + val o = object {} + assertEquals(null, o.javaClass.kotlin.qualifiedName) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/classes/starProjectedType.kt b/backend.native/tests/external/codegen/blackbox/reflection/classes/starProjectedType.kt new file mode 100644 index 00000000000..2acc65853e5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/classes/starProjectedType.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KTypeProjection +import kotlin.reflect.full.createType +import kotlin.reflect.full.starProjectedType +import kotlin.test.assertEquals + +class Foo + +fun box(): String { + val foo = Foo::class.starProjectedType + assertEquals(Foo::class, foo.classifier) + assertEquals(listOf(KTypeProjection.STAR, KTypeProjection.STAR), foo.arguments) + assertEquals(foo, Foo::class.createType(listOf(KTypeProjection.STAR, KTypeProjection.STAR))) + + assertEquals(String::class, String::class.starProjectedType.classifier) + assertEquals(listOf(), String::class.starProjectedType.arguments) + + val tp = Foo::class.typeParameters.first() + assertEquals(tp.createType(), tp.starProjectedType) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/constructors/annotationClass.kt b/backend.native/tests/external/codegen/blackbox/reflection/constructors/annotationClass.kt new file mode 100644 index 00000000000..2975eaefe18 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/constructors/annotationClass.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.test.assertEquals + +annotation class A1 + +annotation class A2(val k: KClass<*>, val s: A1) + +fun box(): String { + assertEquals(1, A1::class.constructors.size) + assertEquals(A1::class.primaryConstructor, A1::class.constructors.single()) + + val cs = A2::class.constructors + assertEquals(1, cs.size) + assertEquals(A2::class.primaryConstructor, cs.single()) + val params = cs.single().parameters + assertEquals(listOf("k", "s"), params.map { it.name }) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/constructors/classesWithoutConstructors.kt b/backend.native/tests/external/codegen/blackbox/reflection/constructors/classesWithoutConstructors.kt new file mode 100644 index 00000000000..5f78791ff90 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/constructors/classesWithoutConstructors.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertTrue + +interface Interface +object Obj + +class C { + companion object +} + +fun box(): String { + assertTrue(Interface::class.constructors.isEmpty()) + assertTrue(Obj::class.constructors.isEmpty()) + assertTrue(C.Companion::class.constructors.isEmpty()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/constructors/constructorName.kt b/backend.native/tests/external/codegen/blackbox/reflection/constructors/constructorName.kt new file mode 100644 index 00000000000..2b1ddf08566 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/constructors/constructorName.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +class A + +fun box(): String { + assertEquals("", ::A.name) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/constructors/primaryConstructor.kt b/backend.native/tests/external/codegen/blackbox/reflection/constructors/primaryConstructor.kt new file mode 100644 index 00000000000..2647d082f2c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/constructors/primaryConstructor.kt @@ -0,0 +1,57 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertNull +import kotlin.test.assertNotNull +import kotlin.reflect.* + +class OnlyPrimary + +class PrimaryWithSecondary(val s: String) { + constructor(x: Int) : this(x.toString()) + + override fun toString() = s +} + +class OnlySecondary { + constructor(s: String) +} + +class TwoSecondaries { + constructor(s: String) + constructor(d: Double) +} + +enum class En + +interface I +object O +class C { + companion object +} + +fun box(): String { + val p1 = OnlyPrimary::class.primaryConstructor + assertNotNull(p1) + assert(p1!!.call() is OnlyPrimary) + + val p2 = PrimaryWithSecondary::class.primaryConstructor + assertNotNull(p2) + assert(p2!!.call("beer").toString() == "beer") + + val p3 = OnlySecondary::class.primaryConstructor + assertNull(p3) + + val p4 = TwoSecondaries::class.primaryConstructor + assertNull(p4) + + assertNotNull(En::class.primaryConstructor) // TODO: maybe primaryConstructor should be null for enum classes + + assertNull(I::class.primaryConstructor) + assertNull(O::class.primaryConstructor) + assertNull(C.Companion::class.primaryConstructor) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/constructors/simpleGetConstructors.kt b/backend.native/tests/external/codegen/blackbox/reflection/constructors/simpleGetConstructors.kt new file mode 100644 index 00000000000..0d50c329b73 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/constructors/simpleGetConstructors.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import java.util.Collections +import kotlin.reflect.* +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +open class A private constructor(x: Int) { + public constructor(s: String): this(s.length) + constructor(): this("") +} + +class B : A("") + +class C { + class Nested + inner class Inner +} + +fun box(): String { + assertEquals(3, A::class.constructors.size) + assertEquals(1, B::class.constructors.size) + + assertTrue(Collections.disjoint(A::class.members, A::class.constructors)) + assertTrue(Collections.disjoint(B::class.members, B::class.constructors)) + + assertEquals(1, C.Nested::class.constructors.size) + assertEquals(1, C.Inner::class.constructors.size) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/annotationType.kt b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/annotationType.kt new file mode 100644 index 00000000000..ca87362f349 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/annotationType.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +annotation class Foo + +fun box(): String { + val foo = Foo::class.constructors.single().call() + assertEquals(Foo::class, foo.annotationClass) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/arrayOfKClasses.kt b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/arrayOfKClasses.kt new file mode 100644 index 00000000000..b4f2c301ffd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/arrayOfKClasses.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KClass +import kotlin.test.assertEquals + +annotation class Anno(val klasses: Array> = arrayOf(String::class, Int::class)) + +fun box(): String { + val anno = Anno::class.constructors.single().callBy(emptyMap()) + assertEquals(listOf(String::class, Int::class), (anno.klasses as Array>).toList() /* TODO: KT-9453 */) + assertEquals("@Anno(klasses=[class java.lang.String, int])", anno.toString()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/callByJava.kt b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/callByJava.kt new file mode 100644 index 00000000000..e1410183b37 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/callByJava.kt @@ -0,0 +1,81 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public interface J { + @interface NoParams {} + + @interface OneDefault { + String s() default "OK"; + } + + @interface OneNonDefault { + String s(); + } + + @interface TwoParamsOneDefault { + String s(); + int x() default 42; + } + + @interface TwoNonDefaults { + String string(); + Class clazz(); + } + + @interface ManyDefaultParams { + int i() default 0; + String s() default ""; + double d() default 3.14; + } +} + +// FILE: K.kt + +import J.* +import kotlin.reflect.KClass +import kotlin.reflect.primaryConstructor +import kotlin.test.assertEquals +import kotlin.test.assertFails + +inline fun create(args: Map): T { + val ctor = T::class.constructors.single() + return ctor.callBy(args.mapKeys { entry -> ctor.parameters.single { it.name == entry.key } }) +} + +inline fun create(): T = create(emptyMap()) + +fun box(): String { + create() + + val t1 = create() + assertEquals("OK", t1.s) + assertFails { create(mapOf("s" to 42)) } + + val t2 = create(mapOf("s" to "OK")) + assertEquals("OK", t2.s) + assertFails { create() } + + val t3 = create(mapOf("s" to "OK")) + assertEquals("OK", t3.s) + assertEquals(42, t3.x) + val t4 = create(mapOf("s" to "OK", "x" to 239)) + assertEquals(239, t4.x) + assertFails { create(mapOf("s" to "Fail", "x" to "Fail")) } + + assertFails("KClass (not Class) instances should be passed as arguments") { + create(mapOf("clazz" to String::class.java, "string" to "Fail")) + } + + val t5 = create(mapOf("clazz" to String::class, "string" to "OK")) + assertEquals("OK", t5.string) + + val t6 = create() + assertEquals(0, t6.i) + assertEquals("", t6.s) + assertEquals(3.14, t6.d) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/callByKotlin.kt b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/callByKotlin.kt new file mode 100644 index 00000000000..7b2db38d382 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/callByKotlin.kt @@ -0,0 +1,53 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KClass +import kotlin.reflect.primaryConstructor +import kotlin.test.assertEquals +import kotlin.test.assertFails + +annotation class NoParams +annotation class OneDefault(val s: String = "OK") +annotation class OneNonDefault(val s: String) +annotation class TwoParamsOneDefault(val s: String, val x: Int = 42) +annotation class TwoParamsOneDefaultKClass(val string: String, val klass: KClass<*> = Number::class) +annotation class TwoNonDefaults(val string: String, val klass: KClass<*>) + + +inline fun create(args: Map): T { + val ctor = T::class.constructors.single() + return ctor.callBy(args.mapKeys { entry -> ctor.parameters.single { it.name == entry.key } }) +} + +inline fun create(): T = create(emptyMap()) + +fun box(): String { + create() + + val t1 = create() + assertEquals("OK", t1.s) + assertFails { create(mapOf("s" to 42)) } + + val t2 = create(mapOf("s" to "OK")) + assertEquals("OK", t2.s) + assertFails { create() } + + val t3 = create(mapOf("s" to "OK")) + assertEquals("OK", t3.s) + assertEquals(42, t3.x) + val t4 = create(mapOf("s" to "OK", "x" to 239)) + assertEquals(239, t4.x) + assertFails { create(mapOf("s" to "Fail", "x" to "Fail")) } + + val t5 = create(mapOf("string" to "OK")) + assertEquals(Number::class, t5.klass as KClass<*> /* TODO: KT-9453 */) + + assertFails("KClass (not Class) instances should be passed as arguments") { + create(mapOf("klass" to String::class.java, "string" to "Fail")) + } + + val t6 = create(mapOf("klass" to String::class, "string" to "OK")) + return t6.string +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/callJava.kt b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/callJava.kt new file mode 100644 index 00000000000..48adf7d623c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/callJava.kt @@ -0,0 +1,93 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public interface J { + @interface NoParams {} + + @interface OneDefault { + String foo() default "foo"; + } + + @interface OneDefaultValue { + String value() default "value"; + } + + @interface OneNonDefault { + String foo(); + } + + @interface OneNonDefaultValue { + String value(); + } + + @interface TwoParamsOneDefault { + String string(); + Class clazz() default Object.class; + } + + @interface TwoParamsOneValueOneDefault { + String value(); + Class clazz() default Object.class; + } + + @interface TwoNonDefaults { + String string(); + Class clazz(); + } + + @interface ManyDefaults { + int i() default 0; + String s() default ""; + double d() default 3.14; + } +} + +// FILE: K.kt + +import J.* +import kotlin.reflect.KClass +import kotlin.reflect.primaryConstructor +import kotlin.test.assertEquals +import kotlin.test.assertFails + +inline fun create(vararg args: Any?): T = + T::class.constructors.single().call(*args) + +fun box(): String { + create() + + assertFails { create() } + assertFails { create("") } + assertFails { create("", "") } + + assertFails { create() } + create("") + assertFails { create("", "") } + + assertFails { create() } + assertFails { create("") } + + assertFails { create() } + create("") + + assertFails { create() } + assertFails { create("") } + assertFails { create("", Any::class) } + assertFails { create(Any::class, "") } + + assertFails { create() } + assertFails { create("") } + assertFails { create("", Any::class) } + assertFails { create(Any::class, "") } + + assertFails { create("", Any::class) } + assertFails { create(Any::class, "") } + + assertFails { create() } + assertFails { create(42, "Fail", 2.72) } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/callKotlin.kt b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/callKotlin.kt new file mode 100644 index 00000000000..d89d316c6a6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/callKotlin.kt @@ -0,0 +1,38 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KClass +import kotlin.reflect.primaryConstructor +import kotlin.test.assertEquals +import kotlin.test.assertFails + +annotation class NoParams +annotation class OneDefault(val s: String = "Fail") +annotation class TwoNonDefaults(val string: String, val klass: KClass<*>) + +inline fun create(vararg args: Any?): T = + T::class.constructors.single().call(*args) + +fun box(): String { + create() + assertFails { create("Fail") } + + assertFails { create() } + assertFails { create(42) } + val o = create("OK") + assertEquals("OK", o.s) + + assertFails("call() should fail because arguments were passed in an incorrect order") { + create(Any::class, "Fail") + } + assertFails("call() should fail because KClass (not Class) instances should be passed as arguments") { + create("Fail", Any::class.java) + } + + val k = create("OK", Int::class) + assertEquals(Int::class, k.klass as KClass<*> /* TODO: KT-9453 */) + + return k.string +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/createJdkAnnotationInstance.kt b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/createJdkAnnotationInstance.kt new file mode 100644 index 00000000000..14441c3449b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/createJdkAnnotationInstance.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import java.lang.annotation.Retention +import java.lang.annotation.RetentionPolicy +import kotlin.test.assertEquals + +fun box(): String { + val ctor = Retention::class.constructors.single() + val r = ctor.callBy(mapOf( + ctor.parameters.single { it.name == "value" } to RetentionPolicy.RUNTIME + )) + assertEquals(RetentionPolicy.RUNTIME, r.value as RetentionPolicy) + assertEquals(Retention::class.java.classLoader, r.javaClass.classLoader) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/enumKClassAnnotation.kt b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/enumKClassAnnotation.kt new file mode 100644 index 00000000000..7dcb9223716 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/enumKClassAnnotation.kt @@ -0,0 +1,50 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KClass +import kotlin.test.assertEquals + +annotation class Foo(val value: String) + +annotation class Anno( + val level: DeprecationLevel, + val klass: KClass<*>, + val foo: Foo, + val levels: Array, + val klasses: Array>, + val foos: Array +) + +@Anno( + DeprecationLevel.WARNING, + Number::class, + Foo("OK"), + arrayOf(DeprecationLevel.WARNING), + arrayOf(Number::class), + arrayOf(Foo("OK")) +) +fun foo() {} + +fun box(): String { + // Construct an annotation with exactly the same parameters, check that the proxy created by Kotlin and by Java reflection are the same and have the same hash code + val a1 = Anno::class.constructors.single().call( + DeprecationLevel.WARNING, + Number::class, + Foo::class.constructors.single().call("OK"), + arrayOf(DeprecationLevel.WARNING), + arrayOf(Number::class), + arrayOf(Foo::class.constructors.single().call("OK")) + ) + val a2 = ::foo.annotations.single() as Anno + + assertEquals(a1, a2) + assertEquals(a2, a1) + assertEquals(a1.hashCode(), a2.hashCode()) + + assertEquals("@Anno(level=WARNING, klass=class java.lang.Number, foo=@Foo(value=OK), " + + "levels=[WARNING], klasses=[class java.lang.Number], foos=[@Foo(value=OK)])", a1.toString()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/equalsHashCodeToString.kt b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/equalsHashCodeToString.kt new file mode 100644 index 00000000000..7ffbee7dfb3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/equalsHashCodeToString.kt @@ -0,0 +1,49 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +package test + +annotation class A +annotation class B(val s: String) + +@A +@B("2") +fun javaReflectionAnnotationInstances() {} + +fun box(): String { + val createA = A::class.constructors.single() + + val a1 = createA.call() + if (a1.toString() != "@test.A()") return "Fail: toString does not correspond to the documentation of java.lang.annotation.Annotation#toString: $a1" + + val a2 = createA.call() + if (a1 === a2) return "Fail: instances created by the constructor should be different" + if (a1 != a2) return "Fail: any instance of A should be equal to any other instance of A" + if (a1.hashCode() != a2.hashCode()) return "Fail: hash codes of equal instances should be equal" + if (a1.hashCode() != 0) return "Fail: hashCode does not correspond to the documentation of java.lang.annotation.Annotation#hashCode: ${a1.hashCode()}" + + val createB = B::class.constructors.single() + val b1 = createB.call("1") + if (b1.toString() != "@test.B(s=1)") return "Fail: toString does not correspond to the documentation of java.lang.annotation.Annotation#toString: $b1" + if (b1 != b1) return "Fail: instance should be equal to itself" + + val b2 = createB.call("2") + if (b1 == b2) return "Fail: instances with different data should not be equal" + if (b1.hashCode() == b2.hashCode()) return "Fail: hash codes of different instances should very likely be also different" + + val a3 = ::javaReflectionAnnotationInstances.annotations.filterIsInstance().single() + if (a1 === a3) return "Fail: instance created by the constructor and the one obtained from Java reflection should be different" + if (a1 != a3) return "Fail: instance created by the constructor should be equal to the one obtained from Java reflection" + if (a3 != a1) return "Fail: instance obtained from Java reflection should be equal to the one created by the constructor" + if (a1.hashCode() != a3.hashCode()) return "Fail: hash codes of equal instances should be equal" + + val b3 = ::javaReflectionAnnotationInstances.annotations.filterIsInstance().single() + if (b2 === b3) return "Fail: instance created by the constructor and the one obtained from Java reflection should be different" + if (b2 != b3) return "Fail: instance created by the constructor should be equal to the one obtained from Java reflection" + if (b3 != b2) return "Fail: instance obtained from Java reflection should be equal to the one created by the constructor" + if (b2.hashCode() != b3.hashCode()) return "Fail: hash codes of equal instances should be equal" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/floatingPointParameters.kt b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/floatingPointParameters.kt new file mode 100644 index 00000000000..a3fff2faa64 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/floatingPointParameters.kt @@ -0,0 +1,66 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals +import kotlin.test.assertNotEquals + +annotation class D(val d: Double) +annotation class F(val f: Float) + +/* +// TODO: uncomment once KT-13887 is implemented +@D(Double.NaN) +fun dnan() {} + +@F(Float.NaN) +fun fnan() {} +*/ + +@D(-0.0) +fun dMinusZero() {} +@D(+0.0) +fun dPlusZero() {} + +@F(-0.0f) +fun fMinusZero() {} +@F(+0.0f) +fun fPlusZero() {} + +fun check(x: Any, y: Any) { + assertEquals(x, y) + assertEquals(y, x) + assertEquals(x.hashCode(), y.hashCode()) + assertEquals(x.toString(), y.toString()) +} + +fun checkNot(x: Any, y: Any) { + assertNotEquals(x, y) + assertNotEquals(y, x) + assertNotEquals(x.hashCode(), y.hashCode()) + assertNotEquals(x.toString(), y.toString()) +} + +fun box(): String { +/* + check(::dnan.annotations.single() as D, D::class.constructors.single().call(Double.NaN)) + check(::fnan.annotations.single() as F, F::class.constructors.single().call(Float.NaN)) +*/ + + val dmz = D::class.constructors.single().call(-0.0) + val dpz = D::class.constructors.single().call(+0.0) + val fmz = F::class.constructors.single().call(-0.0f) + val fpz = F::class.constructors.single().call(+0.0f) + check(::dMinusZero.annotations.single() as D, dmz) + check(::dPlusZero.annotations.single() as D, dpz) + check(::fMinusZero.annotations.single() as F, fmz) + check(::fPlusZero.annotations.single() as F, fpz) + + checkNot(dmz, dpz) + checkNot(fmz, fpz) + checkNot(dmz, fmz) + checkNot(dpz, fpz) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/parameterNamedEquals.kt b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/parameterNamedEquals.kt new file mode 100644 index 00000000000..3058ac7238b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/parameterNamedEquals.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals +import kotlin.test.assertNotEquals + +annotation class Anno(val equals: Boolean) + +fun box(): String { + val t = Anno::class.constructors.single().call(true) + val f = Anno::class.constructors.single().call(false) + assertEquals(true, t.equals) + assertEquals(false, f.equals) + assertNotEquals(t, f) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/primitivesAndArrays.kt b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/primitivesAndArrays.kt new file mode 100644 index 00000000000..b33fcee14a2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/createAnnotation/primitivesAndArrays.kt @@ -0,0 +1,85 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +annotation class Anno( + val b: Byte, + val c: Char, + val d: Double, + val f: Float, + val i: Int, + val j: Long, + val s: Short, + val z: Boolean, + val ba: ByteArray, + val ca: CharArray, + val da: DoubleArray, + val fa: FloatArray, + val ia: IntArray, + val ja: LongArray, + val sa: ShortArray, + val za: BooleanArray, + val str: String, + val stra: Array +) + +@Anno( + 1.toByte(), + 'x', + 3.14, + -2.72f, + 42424242, + 239239239239239L, + 42.toShort(), + true, + byteArrayOf((-1).toByte()), + charArrayOf('y'), + doubleArrayOf(-3.14159), + floatArrayOf(2.7218f), + intArrayOf(424242), + longArrayOf(239239239239L), + shortArrayOf((-43).toShort()), + booleanArrayOf(false, true), + "lol", + arrayOf("rofl") +) +fun foo() {} + +fun box(): String { + // Construct an annotation with exactly the same parameters, check that the proxy created by Kotlin and by Java reflection are the same and have the same hash code + val a1 = Anno::class.constructors.single().call( + 1.toByte(), + 'x', + 3.14, + -2.72f, + 42424242, + 239239239239239L, + 42.toShort(), + true, + byteArrayOf((-1).toByte()), + charArrayOf('y'), + doubleArrayOf(-3.14159), + floatArrayOf(2.7218f), + intArrayOf(424242), + longArrayOf(239239239239L), + shortArrayOf((-43).toShort()), + booleanArrayOf(false, true), + "lol", + arrayOf("rofl") + ) + + val a2 = ::foo.annotations.single() as Anno + + assertEquals(a1, a2) + assertEquals(a2, a1) + assertEquals(a1.hashCode(), a2.hashCode()) + + assertEquals("@Anno(b=1, c=x, d=3.14, f=-2.72, i=42424242, j=239239239239239, s=42, z=true, " + + "ba=[-1], ca=[y], da=[-3.14159], fa=[2.7218], ia=[424242], ja=[239239239239], sa=[-43], za=[false, true], " + + "str=lol, stra=[rofl])", a1.toString()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/anonymousObjectInInlinedLambda.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/anonymousObjectInInlinedLambda.kt new file mode 100644 index 00000000000..c94bfe8536b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/anonymousObjectInInlinedLambda.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +interface A { + fun f(): String +} + +inline fun foo(): A { + return object : A { + override fun f(): String { + return "OK" + } + } +} + +fun box(): String { + val y = foo() + + val enclosing = y.javaClass.getEnclosingMethod() + if (enclosing?.getName() != "foo") return "method: $enclosing" + + return y.f() +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/classInLambda.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/classInLambda.kt new file mode 100644 index 00000000000..aebe9683946 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/classInLambda.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +fun box(): String { + + val classInLambda = { + class Z {} + Z() + }() + + val enclosingMethod = classInLambda.javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "invoke") return "method: $enclosingMethod" + + val enclosingClass = classInLambda.javaClass.getEnclosingClass()!!.getName() + if (enclosingClass != "ClassInLambdaKt\$box\$classInLambda\$1") return "enclosing class: $enclosingClass" + + val declaringClass = classInLambda.javaClass.getDeclaringClass() + if (declaringClass != null) return "class has a declaring class" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/functionExpressionInProperty.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/functionExpressionInProperty.kt new file mode 100644 index 00000000000..78fe21efa72 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/functionExpressionInProperty.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +val property = fun () {} + +fun box(): String { + val javaClass = property.javaClass + + val enclosingMethod = javaClass.getEnclosingMethod() + if (enclosingMethod != null) return "method: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass()!!.getName() + if (enclosingClass != "FunctionExpressionInPropertyKt") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/kt11969.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/kt11969.kt new file mode 100644 index 00000000000..25c55218a4f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/kt11969.kt @@ -0,0 +1,63 @@ +// WITH_RUNTIME +// IGNORE_BACKEND: JS, NATIVE + +interface Z { + private fun privateFun() = { "OK" } + + fun callPrivateFun() = privateFun() + + fun publicFun() = { "OK" } + + fun funWithDefaultArgs(s: () -> Unit = {}): () -> Unit + + val property: () -> Unit + get() = {} + + class Nested +} + +class Test : Z { + override fun funWithDefaultArgs(s: () -> Unit): () -> Unit { + return s + } + + fun funWithDefaultArgsInClass(s: () -> Unit = {}): () -> Unit { + return s + } +} + +fun box(): String { + + val privateFun = Test().callPrivateFun() + var enclosing = privateFun.javaClass.enclosingMethod!! + if (enclosing.name != "privateFun") return "fail 1: ${enclosing.name}" + if (enclosing.getDeclaringClass().simpleName != "DefaultImpls") return "fail 2: ${enclosing.getDeclaringClass().simpleName}" + + val publicFun = Test().publicFun() + enclosing = publicFun.javaClass.enclosingMethod!! + if (enclosing.name != "publicFun") return "fail 3: ${enclosing.name}" + if (enclosing.getDeclaringClass().simpleName != "DefaultImpls") return "fail 4: ${enclosing.getDeclaringClass().simpleName}" + + val property = Test().property + enclosing = property.javaClass.enclosingMethod!! + if (enclosing.name != "getProperty") return "fail 4: ${enclosing.name}" + if (enclosing.getDeclaringClass().simpleName != "DefaultImpls") return "fail 5: ${enclosing.getDeclaringClass().simpleName}" + + val defaultArgs = Test().funWithDefaultArgs() + enclosing = defaultArgs.javaClass.enclosingMethod!! + if (enclosing.name != "funWithDefaultArgs\$default") return "fail 6: ${enclosing.name}" + if (enclosing.parameterTypes.size != 4) return "fail 7: not default method ${enclosing.name}" + if (enclosing.getDeclaringClass().simpleName != "DefaultImpls") return "fail 8: ${enclosing.getDeclaringClass().simpleName}" + + val defaultArgsInClass = Test().funWithDefaultArgsInClass() + enclosing = defaultArgsInClass.javaClass.enclosingMethod!! + if (enclosing.name != "funWithDefaultArgsInClass\$default") return "fail 6: ${enclosing.name}" + if (enclosing.parameterTypes.size != 4) return "fail 7: not default method ${enclosing.name}" + if (enclosing.getDeclaringClass().simpleName != "Test") return "fail 8: ${enclosing.getDeclaringClass().simpleName}" + + val nested = Z.Nested::class.java + val enclosingClass = nested.enclosingClass!! + if (enclosingClass.name != "Z") return "fail 9: ${enclosingClass.name}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/kt6368.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/kt6368.kt new file mode 100644 index 00000000000..8d98e81d56c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/kt6368.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import java.util.HashMap + +interface R { + fun result(): String +} + +val a by lazy { + with(HashMap()) { + put("result", object : R { + override fun result(): String = "OK" + }) + this + } +} + +fun box(): String { + val r = a["result"]!! + + // Check that reflection won't fail + r.javaClass.getEnclosingMethod().toString() + + return r.result() +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/kt6691_lambdaInSamConstructor.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/kt6691_lambdaInSamConstructor.kt new file mode 100644 index 00000000000..a7192acd479 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/kt6691_lambdaInSamConstructor.kt @@ -0,0 +1,29 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +var lambda = {} + +class A { + val prop = Runnable { + lambda = { println("") } + } +} + +fun box(): String { + A().prop.run() + + val javaClass = lambda.javaClass + + val enclosingMethod = javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "run") return "method: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass()!!.getName() + if (enclosingClass != "A\$prop\$1") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInClassObject.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInClassObject.kt new file mode 100644 index 00000000000..1fd22c3f3a0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInClassObject.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +class O { + companion object { + // Currently we consider in class O as the enclosing method of this lambda, + // so we write outer class = O and enclosing method = null + val f = {} + } +} + +fun box(): String { + val javaClass = O.f.javaClass + + val enclosingMethod = javaClass.getEnclosingMethod() + if (enclosingMethod != null) return "method: $enclosingMethod" + + val enclosingConstructor = javaClass.getEnclosingConstructor() + if (enclosingConstructor != null) return "constructor: $enclosingConstructor" + + val enclosingClass = javaClass.getEnclosingClass() + if (enclosingClass?.getName() != "O") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInConstructor.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInConstructor.kt new file mode 100644 index 00000000000..9743cdf3e41 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInConstructor.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +class C { + val l: Any = {} +} + +fun box(): String { + val javaClass = C().l.javaClass + val enclosingConstructor = javaClass.getEnclosingConstructor() + if (enclosingConstructor?.getDeclaringClass()?.getName() != "C") return "ctor: $enclosingConstructor" + + val enclosingClass = javaClass.getEnclosingClass() + if (enclosingClass?.getName() != "C") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInFunction.kt new file mode 100644 index 00000000000..f04e3e95611 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInFunction.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +fun box(): String { + val l: Any = {} + + val javaClass = l.javaClass + val enclosingMethod = javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "box") return "method: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass()!!.getName() + if (enclosingClass != "LambdaInFunctionKt") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInLambda.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInLambda.kt new file mode 100644 index 00000000000..b6fb1f42c0f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInLambda.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +fun box(): String { + val l = { + {} + } + + val javaClass = l().javaClass + val enclosingMethod = javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "invoke") return "method: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass()!!.getName() + if (enclosingClass != "LambdaInLambdaKt\$box\$l\$1") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInLocalClassConstructor.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInLocalClassConstructor.kt new file mode 100644 index 00000000000..1a38dfda515 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInLocalClassConstructor.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +open class C + +fun box(): String { + class L : C() { + val a: Any + + init { + a = {} + } + } + val l = L() + + val javaClass = l.a.javaClass + val enclosingMethod = javaClass.getEnclosingConstructor()!!.getName() + if (enclosingMethod != "LambdaInLocalClassConstructorKt\$box\$L") return "ctor: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass()!!.getName() + if (enclosingClass != "LambdaInLocalClassConstructorKt\$box\$L") return "enclosing class: $enclosingClass" + + if (enclosingMethod != enclosingClass) return "$enclosingClass != $enclosingMethod" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInLocalClassSuperCall.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInLocalClassSuperCall.kt new file mode 100644 index 00000000000..78aa1870a79 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInLocalClassSuperCall.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +open class C(val a: Any) + +fun box(): String { + class L : C({}) { + } + val l = L() + + val javaClass = l.a.javaClass + val enclosingMethod = javaClass.getEnclosingConstructor()!!.getName() + if (enclosingMethod != "LambdaInLocalClassSuperCallKt\$box\$L") return "ctor: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass()!!.getName() + if (enclosingClass != "LambdaInLocalClassSuperCallKt\$box\$L") return "enclosing class: $enclosingClass" + + if (enclosingMethod != enclosingClass) return "$enclosingClass != $enclosingMethod" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInLocalFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInLocalFunction.kt new file mode 100644 index 00000000000..04109f92754 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInLocalFunction.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +fun box(): String { + fun foo(): Any { + return {} + } + + val javaClass = foo().javaClass + val enclosingMethod = javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "invoke") return "method: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass()!!.getName() + if (enclosingClass != "LambdaInLocalFunctionKt\$box$1") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInMemberFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInMemberFunction.kt new file mode 100644 index 00000000000..91d1cee05d2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInMemberFunction.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +class C { + fun foo(): Any { + return {} + } +} + + +fun box(): String { + val javaClass = C().foo().javaClass + val enclosingMethod = javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "foo") return "method: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass() + if (enclosingClass?.getName() != "C") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInMemberFunctionInLocalClass.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInMemberFunctionInLocalClass.kt new file mode 100644 index 00000000000..883f10ba9a8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInMemberFunctionInLocalClass.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +fun box(): String { + class C { + fun foo(): Any { + return {} + } + } + + val javaClass = C().foo().javaClass + val enclosingMethod = javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "foo") return "method: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass()!!.getName() + if (enclosingClass != "LambdaInMemberFunctionInLocalClassKt\$box\$C") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInMemberFunctionInNestedClass.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInMemberFunctionInNestedClass.kt new file mode 100644 index 00000000000..caa749c8d3a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInMemberFunctionInNestedClass.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +class C { + class D { + fun foo(): Any { + return {} + } + } +} + +fun box(): String { + val javaClass = C.D().foo().javaClass + val enclosingMethod = javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "foo") return "method: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass() + if (enclosingClass?.getSimpleName() != "D") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInObjectDeclaration.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInObjectDeclaration.kt new file mode 100644 index 00000000000..de061c4090a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInObjectDeclaration.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +object O { + val f = {} +} + +fun box(): String { + val javaClass = O.f.javaClass + + val enclosingMethod = javaClass.getEnclosingMethod() + if (enclosingMethod != null) return "method: $enclosingMethod" + + val enclosingConstructor = javaClass.getEnclosingConstructor() + if (enclosingConstructor == null) return "no enclosing constructor" + + val enclosingClass = javaClass.getEnclosingClass() + if (enclosingClass?.getName() != "O") return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInObjectExpression.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInObjectExpression.kt new file mode 100644 index 00000000000..16dd43b0f6f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInObjectExpression.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +interface C { + val a: Any +} + +fun box(): String { + val l = object : C { + override val a: Any + + init { + a = {} + } + } + + val javaClass = l.a.javaClass + val enclosingMethod = javaClass.getEnclosingConstructor()!!.getName() + if (enclosingMethod != "LambdaInObjectExpressionKt\$box\$l\$1") return "ctor: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass()!!.getName() + if (enclosingClass != "LambdaInObjectExpressionKt\$box\$l\$1") return "enclosing class: $enclosingClass" + + if (enclosingMethod != enclosingClass) return "$enclosingClass != $enclosingMethod" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInObjectLiteralSuperCall.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInObjectLiteralSuperCall.kt new file mode 100644 index 00000000000..1d9a7c51dae --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInObjectLiteralSuperCall.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +open class C(val a: Any) + +fun box(): String { + val l = object : C({}) { + } + + val javaClass = l.a.javaClass + if (javaClass.getEnclosingConstructor() != null) return "ctor should be null" + + val enclosingMethod = javaClass.getEnclosingMethod()!!.getName() + if (enclosingMethod != "box") return "method: $enclosingMethod" + + val enclosingClass = javaClass.getEnclosingClass()!!.getName() + if (enclosingClass != "LambdaInObjectLiteralSuperCallKt" || enclosingClass != l.javaClass.getEnclosingClass()!!.getName()) + return "enclosing class: $enclosingClass" + + val declaringClass = javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInPackage.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInPackage.kt new file mode 100644 index 00000000000..5997c2f1103 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInPackage.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +val l: Any = {} + +fun box(): String { + val enclosingClass = l.javaClass.getEnclosingClass()!!.getName() + if (enclosingClass != "LambdaInPackageKt") return "enclosing class: $enclosingClass" + + val enclosingConstructor = l.javaClass.getEnclosingConstructor() + if (enclosingConstructor != null) return "enclosing constructor found: $enclosingConstructor" + + val enclosingMethod = l.javaClass.getEnclosingMethod() + if (enclosingMethod != null) return "enclosing method found: $enclosingMethod" + + val declaringClass = l.javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInPropertyGetter.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInPropertyGetter.kt new file mode 100644 index 00000000000..b31664eaa62 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInPropertyGetter.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +val l: Any + get() = {} + +fun box(): String { + + val enclosingMethod = l.javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "getL") return "method: $enclosingMethod" + + val enclosingClass = l.javaClass.getEnclosingClass()!!.getName() + if (enclosingClass != "LambdaInPropertyGetterKt") return "enclosing class: $enclosingClass" + + val declaringClass = l.javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInPropertySetter.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInPropertySetter.kt new file mode 100644 index 00000000000..fc0f7032d01 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/lambdaInPropertySetter.kt @@ -0,0 +1,27 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +var _l: Any = "" + +var l: Any + get() = _l + set(v) { + _l = {} + } + +fun box(): String { + l = "" // to invoke the setter + + val enclosingMethod = l.javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "setL") return "method: $enclosingMethod" + + val enclosingClass = l.javaClass.getEnclosingClass()!!.getName() + if (enclosingClass != "LambdaInPropertySetterKt") return "enclosing class: $enclosingClass" + + val declaringClass = l.javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous function has a declaring class: $declaringClass" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/localClassInTopLevelFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/localClassInTopLevelFunction.kt new file mode 100644 index 00000000000..c89a0eb159f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/localClassInTopLevelFunction.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// KT-4234 + +fun box(): String { + class C + + val name = C::class.java.getSimpleName() + if (name != "box\$C") return "Fail: $name" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/enclosing/objectInLambda.kt b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/objectInLambda.kt new file mode 100644 index 00000000000..d75d2aff8c8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/enclosing/objectInLambda.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +fun box(): String { + + val objectInLambda = { + object : Any () {} + }() + + val enclosingMethod = objectInLambda.javaClass.getEnclosingMethod() + if (enclosingMethod?.getName() != "invoke") return "method: $enclosingMethod" + + val enclosingClass = objectInLambda.javaClass.getEnclosingClass()!!.getName() + if (enclosingClass != "ObjectInLambdaKt\$box\$objectInLambda\$1") return "enclosing class: $enclosingClass" + + val declaringClass = objectInLambda.javaClass.getDeclaringClass() + if (declaringClass != null) return "anonymous object has a declaring class" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/functions/declaredVsInheritedFunctions.kt b/backend.native/tests/external/codegen/blackbox/reflection/functions/declaredVsInheritedFunctions.kt new file mode 100644 index 00000000000..ffac5fb4245 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/functions/declaredVsInheritedFunctions.kt @@ -0,0 +1,80 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public class J { + public void publicMemberJ() {} + private void privateMemberJ() {} + public static void publicStaticJ() {} + private static void privateStaticJ() {} +} + +// FILE: K.kt + +import kotlin.reflect.* +import kotlin.test.assertEquals + +open class K : J() { + public fun publicMemberK() {} + private fun privateMemberK() {} + public fun Any.publicMemberExtensionK() {} + private fun Any.privateMemberExtensionK() {} +} + +class L : K() + +fun Collection>.names(): Set = + this.map { it.name }.toSet() + +fun check(c: Collection>, names: Set) { + assertEquals(names, c.names()) +} + +fun box(): String { + val any = setOf("equals", "hashCode", "toString") + + val j = J::class + + check(j.staticFunctions, + setOf("publicStaticJ", "privateStaticJ")) + check(j.declaredFunctions, + setOf("publicMemberJ", "privateMemberJ", "publicStaticJ", "privateStaticJ")) + check(j.declaredMemberFunctions, + setOf("publicMemberJ", "privateMemberJ")) + check(j.declaredMemberExtensionFunctions, + emptySet()) + + check(j.functions, any + j.declaredFunctions.names()) + check(j.memberFunctions, any + j.declaredMemberFunctions.names()) + check(j.memberExtensionFunctions, emptySet()) + + val k = K::class + + check(k.staticFunctions, + emptySet()) + check(k.declaredFunctions, + setOf("publicMemberK", "privateMemberK", "publicMemberExtensionK", "privateMemberExtensionK")) + check(k.declaredMemberFunctions, + setOf("publicMemberK", "privateMemberK")) + check(k.declaredMemberExtensionFunctions, + setOf("publicMemberExtensionK", "privateMemberExtensionK")) + + check(k.memberFunctions, any + setOf("publicMemberJ") + k.declaredMemberFunctions.names()) + check(k.memberExtensionFunctions, k.declaredMemberExtensionFunctions.names()) + check(k.functions, any + (k.memberFunctions + k.memberExtensionFunctions).names()) + + + val l = L::class + + check(l.staticFunctions, emptySet()) + check(l.declaredFunctions, emptySet()) + check(l.declaredMemberFunctions, emptySet()) + check(l.declaredMemberExtensionFunctions, emptySet()) + check(l.memberFunctions, any + setOf("publicMemberJ", "publicMemberK")) + check(l.memberExtensionFunctions, setOf("publicMemberExtensionK")) + check(l.functions, any + (l.memberFunctions + l.memberExtensionFunctions).names()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/functions/functionFromStdlib.kt b/backend.native/tests/external/codegen/blackbox/reflection/functions/functionFromStdlib.kt new file mode 100644 index 00000000000..fa08ad98955 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/functions/functionFromStdlib.kt @@ -0,0 +1,10 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +fun doStuff(fn: String.() -> String) = "ok".fn() + +fun box(): String { + return doStuff(String::toUpperCase) +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/functions/functionReferenceErasedToKFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/functions/functionReferenceErasedToKFunction.kt new file mode 100644 index 00000000000..ec5fbcf7a32 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/functions/functionReferenceErasedToKFunction.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +import kotlin.jvm.functions.Function2; +import kotlin.reflect.KFunction; + +public class J { + public static String go() { + KFunction fun = K.Companion.getRef(); + Object result = ((Function2) fun).invoke(new K(), "KO"); + return (String) result; + } +} + +// FILE: K.kt + +class K { + fun reverse(s: String): String { + return s.reversed() + } + + companion object { + fun getRef() = K::reverse + } +} + +fun box(): String { + return J.go() +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/functions/genericOverriddenFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/functions/genericOverriddenFunction.kt new file mode 100644 index 00000000000..983a28a487d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/functions/genericOverriddenFunction.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +interface H { + fun foo(): T? +} + +interface A : H + +fun box(): String { + assertEquals("A?", A::foo.returnType.toString()) + assertEquals("T?", H::foo.returnType.toString()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/functions/instanceOfFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/functions/instanceOfFunction.kt new file mode 100644 index 00000000000..8f8c97a9d59 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/functions/instanceOfFunction.kt @@ -0,0 +1,39 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: FromJava.java + +import kotlin.reflect.KCallable; +import kotlin.jvm.functions.Function1; +import kotlin.jvm.functions.Function2; +import kotlin.jvm.functions.Function3; + +public class FromJava { + public static String test(KCallable x) { + if (!(x instanceof Function1)) return "Fail 6"; + if (!(x instanceof Function2)) return "Fail 7"; + if (!(x instanceof Function3)) return "Fail 8"; + return "OK"; + } +} + +// FILE: test.kt + +class Foo { + fun bar(x: Int): Int = x + 1 +} + +fun box(): String { + val bar = Foo::class.members.single { it.name == "bar" } + + if (bar is Function1<*, *>) return "Fail 1" + if (bar !is Function2<*, *, *>) return "Fail 2" + if (bar is Function3<*, *, *, *>) return "Fail 3" + + bar as? Function2 ?: return "Fail 4" + + if (bar(Foo(), 42) != 43) return "Fail 5" + + return FromJava.test(bar) +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/functions/javaClassGetFunctions.kt b/backend.native/tests/external/codegen/blackbox/reflection/functions/javaClassGetFunctions.kt new file mode 100644 index 00000000000..c4ab712c90f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/functions/javaClassGetFunctions.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public class J { + public J() { + } + + public void member(String s) { + } + + public static void staticMethod(int x) { + } +} + +// FILE: K.kt + +import kotlin.reflect.* +import kotlin.test.assertEquals + +fun box(): String { + assertEquals(listOf("equals", "hashCode", "member", "staticMethod", "toString"), J::class.members.map { it.name }.sorted()) + assertEquals(listOf("equals", "hashCode", "member", "staticMethod", "toString"), J::class.functions.map { it.name }.sorted()) + assertEquals(listOf("member", "staticMethod"), J::class.declaredFunctions.map { it.name }.sorted()) + + assertEquals(1, J::class.constructors.size) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/functions/javaMethodsSmokeTest.kt b/backend.native/tests/external/codegen/blackbox/reflection/functions/javaMethodsSmokeTest.kt new file mode 100644 index 00000000000..513242ff191 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/functions/javaMethodsSmokeTest.kt @@ -0,0 +1,50 @@ +// TARGET_BACKEND: JVM + +// WITH_REFLECT +// FILE: J.java + +import java.util.List; + +public class J { + void simple() {} + + void objectTypes( + Object o, String s, Object[] oo, String[] ss + ) {} + + void primitives( + boolean z, char c, byte b, short s, int i, float f, long j, double d + ) {} + + void primitiveArrays( + boolean[] z, char[] c, byte[] b, short[] s, int[] i, float[] f, long[] j, double[] d + ) {} + + void multiDimensionalArrays( + int[][][] i, Cloneable[][][][] c + ) {} + + void wildcards( + List l, List m + ) {} +} + +// FILE: K.kt + +import kotlin.reflect.KFunction + +// Initiate descriptor computation in reflection to ensure that nothing fails +fun test(f: KFunction<*>) { + f.parameters +} + +fun box(): String { + test(J::simple) + test(J::objectTypes) + test(J::primitives) + test(J::primitiveArrays) + test(J::multiDimensionalArrays) + test(J::wildcards) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/functions/platformName.kt b/backend.native/tests/external/codegen/blackbox/reflection/functions/platformName.kt new file mode 100644 index 00000000000..8968a5b1a51 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/functions/platformName.kt @@ -0,0 +1,9 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +@JvmName("Fail") +fun OK() {} + +fun box() = ::OK.name diff --git a/backend.native/tests/external/codegen/blackbox/reflection/functions/privateMemberFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/functions/privateMemberFunction.kt new file mode 100644 index 00000000000..dd5f92d8869 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/functions/privateMemberFunction.kt @@ -0,0 +1,27 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +class A { + private fun foo() = "A" +} + +fun box(): String { + val f = A::class.declaredFunctions.single() as KFunction + + try { + f.call(A()) + return "Fail: no exception was thrown" + } catch (e: IllegalCallableAccessException) {} + + f.isAccessible = true + + assertEquals("A", f.call(A())) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/functions/simpleGetFunctions.kt b/backend.native/tests/external/codegen/blackbox/reflection/functions/simpleGetFunctions.kt new file mode 100644 index 00000000000..944ad192e54 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/functions/simpleGetFunctions.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* + +open class A { + fun mem() {} + fun Int.memExt() {} +} + +class B : A() + +fun box(): String { + val all = A::class.functions.map { it.name }.sorted() + assert(all == listOf("equals", "hashCode", "mem", "memExt", "toString")) { "Fail A functions: ${A::class.functions}" } + + val declared = A::class.declaredFunctions.map { it.name }.sorted() + assert(declared == listOf("mem", "memExt")) { "Fail A declaredFunctions: ${A::class.declaredFunctions}" } + + val declaredSubclass = B::class.declaredFunctions.map { it.name }.sorted() + assert(declaredSubclass.isEmpty()) { "Fail B declaredFunctions: ${B::class.declaredFunctions}" } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/functions/simpleNames.kt b/backend.native/tests/external/codegen/blackbox/reflection/functions/simpleNames.kt new file mode 100644 index 00000000000..25b3865ae44 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/functions/simpleNames.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +fun foo() {} + +class A { + fun bar() = "" +} + +fun Int.baz() = this + +fun box(): String { + assertEquals("foo", ::foo.name) + assertEquals("bar", A::bar.name) + assertEquals("baz", Int::baz.name) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/covariantOverride.kt b/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/covariantOverride.kt new file mode 100644 index 00000000000..ba746a3107a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/covariantOverride.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +interface A { + fun foo(): Collection +} + +abstract class B : A { + override fun foo(): Collection = null!! +} + +fun box(): String { + val clazz = B::class.java + if (clazz.declaredMethods.first().genericReturnType.toString() != "java.util.Collection") return "fail 1" + + if (clazz.methods.filter { it.name == "foo" }.size != 1) return "fail 2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/defaultImplsGenericSignature.kt b/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/defaultImplsGenericSignature.kt new file mode 100644 index 00000000000..5a32312795a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/defaultImplsGenericSignature.kt @@ -0,0 +1,47 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: J.java + +public class J { + + public static int test1() { + A> x = new X>("O", new B("K")); + return A.DefaultImpls.test1(x, 1, 1.0); + } + + + public static A> test2(){ + X> x = new X>("O", new B("K")); + return A.DefaultImpls.test2(x, 1); + } +} + +// FILE: K.kt + +class B(val value: T) + +interface A> { + + fun test1(p: T, z: L): T { + return p + } + + fun test2(p: L): A { + return this + } +} + + +class X>(val p1: T, val p2: Y) : A { + +} + +fun box(): String { + val test1 = J.test1() + if (test1 != 1) return "fail 1: $test1 != 1" + + val test2: X> = J.test2() as X> + + return test2.p1 + test2.p2.value +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/functionLiteralGenericSignature.kt b/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/functionLiteralGenericSignature.kt new file mode 100644 index 00000000000..419f423375e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/functionLiteralGenericSignature.kt @@ -0,0 +1,36 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +import java.util.Date + +fun assertGenericSuper(expected: String, function: Any?) { + val clazz = (function as java.lang.Object).getClass()!! + val genericSuper = clazz.getGenericInterfaces()[0]!! + if ("$genericSuper" != expected) + throw AssertionError("Fail, expected: $expected, actual: $genericSuper") +} + + +val unitFun = { } +val intFun = { 42 } +val stringParamFun = { x: String -> } +val listFun = { l: List -> l } +val mutableListFun = fun (l: MutableList): MutableList = null!! +val funWithIn = fun (x: Comparable) {} + +val extensionFun = fun Any.() {} +val extensionWithArgFun = fun Long.(x: Any): Date = Date() + +fun box(): String { + assertGenericSuper("kotlin.jvm.functions.Function0", unitFun) + assertGenericSuper("kotlin.jvm.functions.Function0", intFun) + assertGenericSuper("kotlin.jvm.functions.Function1", stringParamFun) + assertGenericSuper("kotlin.jvm.functions.Function1, java.util.List>", listFun) + assertGenericSuper("kotlin.jvm.functions.Function1, java.util.List>", mutableListFun) + assertGenericSuper("kotlin.jvm.functions.Function1, kotlin.Unit>", funWithIn) + + assertGenericSuper("kotlin.jvm.functions.Function1", extensionFun) + assertGenericSuper("kotlin.jvm.functions.Function2", extensionWithArgFun) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/genericBackingFieldSignature.kt b/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/genericBackingFieldSignature.kt new file mode 100644 index 00000000000..aabad1225b1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/genericBackingFieldSignature.kt @@ -0,0 +1,86 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +//test for KT-3722 Write correct generic type information for generated fields +import kotlin.properties.Delegates + +class Z { + +} + +class TParam { + +} + +class Zout { + +} + +class Zin { + +} + + +class Test(val constructorProperty: T) { + + val classField1 : Z? = null + + val classField2 : Z? = null + + val classField3 : Zout? = null + + val classField4 : Zin? = null + + val delegateLazy: Z? by lazy {Z()} + + val delegateNotNull: Z? by Delegates.notNull() + + +} + +fun box(): String { + val clz = Test::class.java + + val constructorProperty = clz.getDeclaredField("constructorProperty"); + + if (constructorProperty.getGenericType().toString() != "T") + return "fail0: " + constructorProperty.getGenericType(); + + + val classField = clz.getDeclaredField("classField1"); + + if (classField.getGenericType().toString() != "Z") + return "fail1: " + classField.getGenericType(); + + + val classField2 = clz.getDeclaredField("classField2"); + + if (classField2.getGenericType().toString() != "Z") + return "fail2: " + classField2.getGenericType(); + + + val classField3 = clz.getDeclaredField("classField3"); + + if (classField3.getGenericType().toString() != "Zout") + return "fail3: " + classField3.getGenericType(); + + + val classField4 = clz.getDeclaredField("classField4"); + + if (classField4.getGenericType().toString() != "Zin") + return "fail4: " + classField4.getGenericType(); + + val classField5 = clz.getDeclaredField("delegateLazy\$delegate"); + + if (classField5.getGenericType().toString() != "interface kotlin.Lazy") + return "fail5: " + classField5.getGenericType(); + + val classField6 = clz.getDeclaredField("delegateNotNull\$delegate"); + + if (classField6.getGenericType().toString() != "interface kotlin.properties.ReadWriteProperty") + return "fail6: " + classField6.getGenericType(); + + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/genericMethodSignature.kt b/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/genericMethodSignature.kt new file mode 100644 index 00000000000..14457a3adef --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/genericMethodSignature.kt @@ -0,0 +1,65 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +class Z {} + +class TParam {} + +class Zout {} + +class Zin {} + +class Params(val methodIndex: Int, val paramClass: Class<*>, val expectedReturnType: String, val expecedParamType: String) + +class Test() { + + fun test1(p: T): T? = null + + fun test2(p: Z): Z? = null + + fun test3(p: Z): Z? = null + + fun test4(p: X): Zout? = null + + fun test5(p: Y): Zin? = null +} + +fun box(): String { + val clz = Test::class.java + + val params = listOf( + Params(1, Any::class.java, "T", "T"), + Params(2, Z::class.java, "Z", "Z"), + Params(3, Z::class.java, "Z", "Z"), + Params(4, Any::class.java, "Zout", "X"), + Params(5, Any::class.java, "Zin", "Y") + ) + + + var result: String = "" + for(p in params) { + val fail = test(clz, p.methodIndex, p.paramClass, p.expectedReturnType, p.expecedParamType) + if (fail != "OK") { + result += fail + "\n"; + } + } + + return if (result.isEmpty()) "OK" else result; + +} + +fun test(clazz: Class<*>, methodIndex: Int, paramClass: Class<*>, expectedReturn : String, expectedParam : String): String { + val method = clazz.getDeclaredMethod("test$methodIndex", paramClass)!!; + + if (method.getGenericReturnType().toString() != expectedReturn) + return "fail$methodIndex: " + method.getGenericReturnType(); + + val test1Param = method.getGenericParameterTypes()!![0]; + + if (test1Param.toString() != expectedParam) + return "fail${methodIndex}_param: " + test1Param; + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/kt11121.kt b/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/kt11121.kt new file mode 100644 index 00000000000..5df300b174d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/kt11121.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +class B + +interface A> { + + fun p(p: T): T { + return p + } + + val T.z : T? + get() = null +} + + +fun box(): String { + val defaultImpls = Class.forName("A\$DefaultImpls") + val declaredMethod = defaultImpls.getDeclaredMethod("p", A::class.java, Any::class.java) + if (declaredMethod.toGenericString() != "public static T A\$DefaultImpls.p(A,T)") return "fail 1: ${declaredMethod.toGenericString()}" + + val declaredProperty = defaultImpls.getDeclaredMethod("getZ", A::class.java, Any::class.java) + if (declaredProperty.toGenericString() != "public static T A\$DefaultImpls.getZ(A,T)") return "fail 2: ${declaredProperty.toGenericString()}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/kt5112.kt b/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/kt5112.kt new file mode 100644 index 00000000000..9c8184c2f67 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/kt5112.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +package test + +class G(val s: T) { + +} + +public interface ErrorsJvmTrait { + companion object { + public val param : G = G("STRING") + } +} + +public class ErrorsJvmClass { + companion object { + @JvmField public val param : G = G("STRING") + } +} + +fun box(): String { + val genericTypeInClassObject = ErrorsJvmTrait.javaClass.getDeclaredField("param").getGenericType() + if (genericTypeInClassObject.toString() != "test.G") return "fail1: $genericTypeInClassObject" + + val genericTypeInClass = ErrorsJvmClass::class.java.getField("param").getGenericType() + if (genericTypeInClass.toString() != "test.G") return "fail1: genericTypeInClass" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/kt6106.kt b/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/kt6106.kt new file mode 100644 index 00000000000..bac5e9c08a8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/genericSignature/kt6106.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +package test + +open class B + +class A { + + companion object { + @JvmStatic + fun a(s: T) : T { + return s + } + } +} + +fun box(): String { + val method = A::class.java.getDeclaredMethod("a", B::class.java) + val genericParameterTypes = method.getGenericParameterTypes() + + if (genericParameterTypes.size != 1) return "Wrong number of generic parameters" + + if (genericParameterTypes[0].toString() != "T") return "Wrong parameter type ${genericParameterTypes[0].toString()}" + + if (method.getGenericReturnType().toString() != "T") return "Wrong return type ${method.getGenericReturnType()}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/isInstance/isInstanceCastAndSafeCast.kt b/backend.native/tests/external/codegen/blackbox/reflection/isInstance/isInstanceCastAndSafeCast.kt new file mode 100644 index 00000000000..3df1d699d1e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/isInstance/isInstanceCastAndSafeCast.kt @@ -0,0 +1,61 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KClass +import kotlin.reflect.full.cast +import kotlin.reflect.full.safeCast +import kotlin.test.* + +fun testInstance(value: Any?, klass: KClass<*>) { + assertTrue(klass.isInstance(value)) + assertEquals(value, klass.safeCast(value)) + assertEquals(value, klass.cast(value)) +} + +fun testNotInstance(value: Any?, klass: KClass<*>) { + assertFalse(klass.isInstance(value)) + assertNull(klass.safeCast(value)) + try { + klass.cast(value) + fail("Value should not be an instance of $klass: $value") + } + catch (e: Exception) { /* OK */ } +} + +fun box(): String { + testInstance(Any(), Any::class) + testInstance("", String::class) + testInstance("", Any::class) + testNotInstance(Any(), String::class) + testNotInstance(null, Any::class) + testNotInstance(null, String::class) + + testInstance(arrayOf(""), Array::class) + testInstance(arrayOf(""), Array::class) + testNotInstance(arrayOf(Any()), Array::class) + + testInstance(listOf(""), List::class) + testInstance(listOf(""), Collection::class) + // TODO: support MutableList::class (KT-11754) + // testNotInstance(listOf(""), MutableList::class) + + testInstance(42, Int::class) + testInstance(42, Int::class.javaPrimitiveType!!.kotlin) + testInstance(42, Int::class.javaObjectType!!.kotlin) + + testNotInstance(3.14, Int::class) + + // Function types + + testInstance(fun() {}, Function0::class) + testNotInstance(fun() {}, Function1::class) + testNotInstance(fun() {}, Function2::class) + + testNotInstance(::testInstance, Function0::class) + testNotInstance(::testInstance, Function1::class) + testInstance(::testInstance, Function2::class) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/array.kt b/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/array.kt new file mode 100644 index 00000000000..3656f3780c5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/array.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KClass + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann(val args: Array>) + +class O +class K + +@Ann(arrayOf(O::class, K::class)) class MyClass + +fun box(): String { + val args = MyClass::class.java.getAnnotation(Ann::class.java).args + val argName1 = args[0].simpleName ?: "fail 1" + val argName2 = args[1].simpleName ?: "fail 2" + return argName1 + argName2 +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/arrayInJava.kt b/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/arrayInJava.kt new file mode 100644 index 00000000000..7fd8ce000ef --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/arrayInJava.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Test.java + +class O {} +class K {} + +@Ann(args={O.class, K.class}) +class Test { +} + +// FILE: array.kt + +import kotlin.reflect.KClass + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann(val args: Array>) + +fun box(): String { + val args = Test::class.java.getAnnotation(Ann::class.java).args + val argName1 = args[0].java.simpleName ?: "fail 1" + val argName2 = args[1].java.simpleName ?: "fail 2" + return argName1 + argName2 +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/basic.kt b/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/basic.kt new file mode 100644 index 00000000000..1b65dbb8618 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/basic.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KClass + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann(val arg: KClass<*>) + +class OK + +@Ann(OK::class) class MyClass + +fun box(): String { + val argName = MyClass::class.java.getAnnotation(Ann::class.java).arg.simpleName ?: "fail 1" + return argName +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/basicInJava.kt b/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/basicInJava.kt new file mode 100644 index 00000000000..c44cc614bf0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/basicInJava.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Test.java + +class OK {} + +@Ann(arg=OK.class) +class Test { +} + +// FILE: basic.kt + +import kotlin.reflect.KClass + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann(val arg: KClass<*>) + +fun box(): String { + val argName = Test::class.java.getAnnotation(Ann::class.java).arg.java.simpleName ?: "fail 1" + return argName +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/checkcast.kt b/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/checkcast.kt new file mode 100644 index 00000000000..9e10e8386a9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/checkcast.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KClass + +fun box(): String { + try { + String::class.java as KClass + } catch (e: Exception) { + return "OK" + } + return "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/vararg.kt b/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/vararg.kt new file mode 100644 index 00000000000..95cfd6a34ac --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/vararg.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KClass + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann(vararg val args: KClass<*>) + +class O +class K + +@Ann(O::class, K::class) class MyClass + +fun box(): String { + val args = MyClass::class.java.getAnnotation(Ann::class.java).args + val argName1 = args[0].simpleName ?: "fail 1" + val argName2 = args[1].simpleName ?: "fail 2" + return argName1 + argName2 +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/varargInJava.kt b/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/varargInJava.kt new file mode 100644 index 00000000000..9756184f351 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/kClassInAnnotation/varargInJava.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Test.java + +class O {} +class K {} + +@Ann(args={O.class, K.class}) +class Test { +} + +// FILE: vararg.kt + +import kotlin.reflect.KClass + +@Retention(AnnotationRetention.RUNTIME) +annotation class Ann(vararg val args: KClass<*>) + +fun box(): String { + val args = Test::class.java.getAnnotation(Ann::class.java).args + val argName1 = args[0].java.simpleName ?: "fail 1" + val argName2 = args[1].java.simpleName ?: "fail 2" + return argName1 + argName2 +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/lambdaClasses/parameterNamesAndNullability.kt b/backend.native/tests/external/codegen/blackbox/reflection/lambdaClasses/parameterNamesAndNullability.kt new file mode 100644 index 00000000000..f5fe5282c06 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/lambdaClasses/parameterNamesAndNullability.kt @@ -0,0 +1,48 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals +import kotlin.test.assertNull + +fun lambda() { + val f = { x: Int, y: String? -> } + + val g = f.reflect()!! + + // TODO: maybe change this name + assertEquals("", g.name) + assertEquals(listOf("x", "y"), g.parameters.map { it.name }) + assertEquals(listOf(false, true), g.parameters.map { it.type.isMarkedNullable }) +} + +fun funExpr() { + val f = fun(x: Int, y: String?) {} + + val g = f.reflect()!! + + // TODO: maybe change this name + assertEquals("", g.name) + assertEquals(listOf("x", "y"), g.parameters.map { it.name }) + assertEquals(listOf(false, true), g.parameters.map { it.type.isMarkedNullable }) +} + +fun extensionFunExpr() { + val f = fun String.(): String = this + + val g = f.reflect()!! + + assertEquals(KParameter.Kind.EXTENSION_RECEIVER, g.parameters.single().kind) + assertEquals(null, g.parameters.single().name) +} + +fun box(): String { + lambda() + funExpr() + extensionFunExpr() + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/constructor.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/constructor.kt new file mode 100644 index 00000000000..dd319ae2ff9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/constructor.kt @@ -0,0 +1,40 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.* + +class K { + class Nested + inner class Inner +} + +class Secondary { + constructor(x: Int) {} +} + +fun check(f: KFunction) { + assert(f.javaMethod == null) { "Fail f method" } + assert(f.javaConstructor != null) { "Fail f constructor" } + val c = f.javaConstructor!! + + assert(c.kotlinFunction != null) { "Fail m function" } + val ff = c.kotlinFunction!! + + assert(f == ff) { "Fail f != ff" } +} + +fun box(): String { + check(::K) + + // Workaround KT-8596 + val nested = K::Nested + check(nested) + + check(K::Inner) + check(::Secondary) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/extensionProperty.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/extensionProperty.kt new file mode 100644 index 00000000000..6af2c80d95c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/extensionProperty.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +class K(var value: Long) + +var K.ext: Double + get() = value.toDouble() + set(value) { + this.value = value.toLong() + } + +fun box(): String { + val p = K::ext + + val getter = p.javaGetter!! + val setter = p.javaSetter!! + + assertEquals(getter, Class.forName("ExtensionPropertyKt").getMethod("getExt", K::class.java)) + assertEquals(setter, Class.forName("ExtensionPropertyKt").getMethod("setExt", K::class.java, Double::class.java)) + + val k = K(42L) + assert(getter.invoke(null, k) == 42.0) { "Fail k getter" } + setter.invoke(null, k, -239.0) + assert(getter.invoke(null, k) == -239.0) { "Fail k setter" } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/fakeOverrides/javaFieldGetterSetter.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/fakeOverrides/javaFieldGetterSetter.kt new file mode 100644 index 00000000000..77067c44a87 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/fakeOverrides/javaFieldGetterSetter.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// KT-8131 Cannot find backing field in ancestor class via reflection + +import kotlin.reflect.* +import kotlin.reflect.jvm.* + +open class TestBase { + var id = 0L +} + +class TestChild : TestBase() + +fun box(): String { + val property = TestChild::class.memberProperties.first { it.name == "id" } as KMutableProperty<*> + if (property.javaField == null) + return "Fail: no field" + if (property.javaGetter == null) + return "Fail: no getter" + if (property.javaSetter == null) + return "Fail: no setter" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/fakeOverrides/javaMethod.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/fakeOverrides/javaMethod.kt new file mode 100644 index 00000000000..04a4aab055f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/fakeOverrides/javaMethod.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.* + +open class TestBase { + fun id() = 0L +} + +class TestChild : TestBase() + +fun box(): String { + if (TestChild::class.memberFunctions.first { it.name == "id" }.javaMethod == null) + return "No method for TestChild.id()" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/functions.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/functions.kt new file mode 100644 index 00000000000..c74a643244d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/functions.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.* + +class K { + fun foo(s: String): Int = s.length +} +fun bar(s: String): Int = s.length +fun String.baz(): Int = this.length + +fun check(f: KFunction) { + assert(f.javaConstructor == null) { "Fail f constructor" } + assert(f.javaMethod != null) { "Fail f method" } + val m = f.javaMethod!! + + assert(m.kotlinFunction != null) { "Fail m function" } + val ff = m.kotlinFunction!! + + assert(f == ff) { "Fail f != ff" } +} + +fun box(): String { + check(K::foo) + check(::bar) + check(String::baz) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/inlineReifiedFun.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/inlineReifiedFun.kt new file mode 100644 index 00000000000..09060b1be71 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/inlineReifiedFun.kt @@ -0,0 +1,23 @@ +// IGNORE_BACKEND: JS, NATIVE +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +inline fun f() = 1 + +fun g() {} + +class Foo { + inline fun h(t: T) = 1 +} + +fun box(): String { + assertEquals(::g, ::g.javaMethod!!.kotlinFunction) + + val h = Foo::class.members.single { it.name == "h" } as KFunction<*> + assertEquals(h, h.javaMethod!!.kotlinFunction) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/jvmStatic/companionObjectFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/jvmStatic/companionObjectFunction.kt new file mode 100644 index 00000000000..ea9f9deac27 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/jvmStatic/companionObjectFunction.kt @@ -0,0 +1,38 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KFunction +import kotlin.reflect.jvm.* +import kotlin.test.* + +class C { + companion object { + @JvmStatic + fun foo(s: String): Int = s.length + } +} + +fun box(): String { + val foo = C.Companion::class.members.single { it.name == "foo" } as KFunction<*> + + val j = foo.javaMethod ?: return "Fail: no Java method found for C::foo" + assertEquals(3, j.invoke(C, "abc")) + + val k = j.kotlinFunction ?: return "Fail: no Kotlin function found for Java method C::foo" + assertEquals(3, k.call(C, "def")) + + + val staticMethod = C::class.java.getDeclaredMethod("foo", String::class.java) + val k2 = staticMethod.kotlinFunction ?: + return "Fail: no Kotlin function found for static bridge for @JvmStatic method in companion object C::foo" + assertEquals(3, k2.call(C, "ghi")) + + assertFailsWith(NullPointerException::class) { k2.call(null, "")!! } + + val j2 = k2.javaMethod + assertEquals(j, j2) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/jvmStatic/objectFunction.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/jvmStatic/objectFunction.kt new file mode 100644 index 00000000000..7e9f2408065 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/jvmStatic/objectFunction.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KFunction +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +object O { + @JvmStatic + fun foo(s: String): Int = s.length +} + +fun box(): String { + val foo = O::class.members.single { it.name == "foo" } as KFunction<*> + + val j = foo.javaMethod ?: return "Fail: no Java method found for O::foo" + assertEquals(3, j.invoke(null, "abc")) + + val k = j.kotlinFunction ?: return "Fail: no Kotlin function found for Java method O::foo" + assertEquals(3, k.call(O, "def")) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/mappedClassIsEqualToClassLiteral.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/mappedClassIsEqualToClassLiteral.kt new file mode 100644 index 00000000000..8b701470811 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/mappedClassIsEqualToClassLiteral.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +class A + +fun box(): String { + val a1 = A::class.java.kotlin + val a2 = A::class + + if (a1 != a2) return "Fail equals" + if (a1.hashCode() != a2.hashCode()) return "Fail hashCode" + if (a1.toString() != a2.toString()) return "Fail toString" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/memberProperty.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/memberProperty.kt new file mode 100644 index 00000000000..dd2063422df --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/memberProperty.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +class K(var value: Long) + +fun box(): String { + val p = K::value + + assert(p.javaField != null) { "Fail p field" } + + val getter = p.javaGetter!! + val setter = p.javaSetter!! + + assertEquals(getter, K::class.java.getMethod("getValue")) + assertEquals(setter, K::class.java.getMethod("setValue", Long::class.java)) + + val k = K(42L) + assert(getter.invoke(k) == 42L) { "Fail k getter" } + setter.invoke(k, -239L) + assert(getter.invoke(k) == -239L) { "Fail k setter" } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/propertyAccessors.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/propertyAccessors.kt new file mode 100644 index 00000000000..6a6c5002b55 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/propertyAccessors.kt @@ -0,0 +1,39 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.* +import kotlin.test.* + +var foo = "foo" + +class A { + var bar = "bar" +} + +fun box(): String { + val fooGetter = ::foo.getter.javaMethod ?: return "Fail fooGetter" + assertEquals("foo", fooGetter.invoke(null)) + + val fooSetter = ::foo.setter.javaMethod ?: return "Fail fooSetter" + fooSetter.invoke(null, "foof") + assertEquals("foof", foo) + + assertNull(::foo.getter.javaConstructor) + assertNull(::foo.setter.javaConstructor) + + + val a = A() + val barGetter = A::bar.getter.javaMethod ?: return "Fail barGetter" + assertEquals("bar", barGetter.invoke(a)) + + val barSetter = A::bar.setter.javaMethod ?: return "Fail barSetter" + barSetter.invoke(a, "barb") + assertEquals("barb", a.bar) + + assertNull(A::bar.getter.javaConstructor) + assertNull(A::bar.setter.javaConstructor) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/propertyAccessorsWithJvmName.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/propertyAccessorsWithJvmName.kt new file mode 100644 index 00000000000..6fe9db0471e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/propertyAccessorsWithJvmName.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.* + +var state: String = "value" + @JvmName("getter") + get + @JvmName("setter") + set + +fun box(): String { + val p = ::state + + if (p.name != "state") return "Fail name: ${p.name}" + if (p.get() != "value") return "Fail get: ${p.get()}" + p.set("OK") + + val getterName = p.javaGetter!!.getName() + if (getterName != "getter") return "Fail getter name: $getterName" + + val setterName = p.javaSetter!!.getName() + if (setterName != "setter") return "Fail setter name: $setterName" + + return p.get() +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/syntheticFields.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/syntheticFields.kt new file mode 100644 index 00000000000..fc43888da85 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/syntheticFields.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.kotlinProperty + +enum class A { + // There's a synthetic field "$VALUES" here +} + +fun box(): String { + for (field in A::class.java.getDeclaredFields()) { + val prop = field.kotlinProperty + if (prop != null) return "Fail, property found: $prop" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/topLevelFunctionOtherFile.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/topLevelFunctionOtherFile.kt new file mode 100644 index 00000000000..a7dfc1caab1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/topLevelFunctionOtherFile.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: test.kt + +fun test2() { +} + +// FILE: main.kt +// See KT-10690 Exception in kotlin.reflect when trying to get kotlinFunction from javaMethod + +import kotlin.reflect.jvm.javaMethod +import kotlin.reflect.jvm.kotlinFunction + +fun box(): String { + if (::box.javaMethod?.kotlinFunction == null) + return "Fail box" + if (::test1.javaMethod?.kotlinFunction == null) + return "Fail test1" + if (::test2.javaMethod?.kotlinFunction == null) + return "Fail test2" + + return "OK" +} + +fun test1() { +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/topLevelProperty.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/topLevelProperty.kt new file mode 100644 index 00000000000..9acdafea053 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/topLevelProperty.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +var topLevel = "123" + +fun box(): String { + val p = ::topLevel + + assert(p.javaField != null) { "Fail p field" } + val field = p.javaField!! + val className = field.getDeclaringClass().getName() + assertEquals("TopLevelPropertyKt", className) + + val getter = p.javaGetter!! + val setter = p.javaSetter!! + + assertEquals(getter, Class.forName("TopLevelPropertyKt").getMethod("getTopLevel")) + assertEquals(setter, Class.forName("TopLevelPropertyKt").getMethod("setTopLevel", String::class.java)) + + assert(getter.invoke(null) == "123") { "Fail k getter" } + setter.invoke(null, "456") + assert(getter.invoke(null) == "456") { "Fail k setter" } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/annotationConstructorParameters.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/annotationConstructorParameters.kt new file mode 100644 index 00000000000..9a7d17c593c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/annotationConstructorParameters.kt @@ -0,0 +1,51 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FULL_JDK + +import java.lang.reflect.GenericArrayType +import java.lang.reflect.ParameterizedType +import kotlin.reflect.KClass +import kotlin.reflect.jvm.javaType +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +annotation class Z +enum class E + +annotation class Anno( + val b: Byte, + val s: String, + val ss: Array, + val z: Z, + val zs: Array, + val e: E, + val es: Array, + val k: KClass<*>, + val ka: Array> +) + +fun tmp(): Array> = null!! + +fun box(): String { + val t = Anno::class.constructors.single().parameters.map { it.type.javaType } + + assertEquals(Byte::class.java, t[0]) + assertEquals(String::class.java, t[1]) + assertEquals(Array::class.java, t[2]) + assertEquals(Z::class.java, t[3]) + assertEquals(Array::class.java, t[4]) + assertEquals(E::class.java, t[5]) + assertEquals(Array::class.java, t[6]) + + assertTrue(t[7] is ParameterizedType) + assertEquals(Class::class.java, (t[7] as ParameterizedType).rawType) + + assertTrue(t[8] is GenericArrayType) + val e = (t[8] as GenericArrayType).genericComponentType + assertTrue(e is ParameterizedType) + assertEquals(Class::class.java, (e as ParameterizedType).rawType) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/array.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/array.kt new file mode 100644 index 00000000000..a977b6b1eea --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/array.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FULL_JDK + +import java.lang.reflect.GenericArrayType +import java.lang.reflect.TypeVariable +import java.lang.reflect.ParameterizedType +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +fun foo(strings: Array, integers: Array, objectArrays: Array>) {} + +fun bar(): Array> = null!! +class A { + fun baz(): Array = null!! +} + +fun box(): String { + assertEquals(Array::class.java, ::foo.parameters[0].type.javaType) + assertEquals(Array::class.java, ::foo.parameters[1].type.javaType) + assertEquals(Array>::class.java, ::foo.parameters[2].type.javaType) + + val g = ::bar.returnType.javaType + if (g !is GenericArrayType || g.genericComponentType !is ParameterizedType) + return "Fail: should be array of parameterized type, but was $g (${g.javaClass})" + + val h = A::baz.returnType.javaType + if (h !is GenericArrayType || h.genericComponentType !is TypeVariable<*>) + return "Fail: should be array of type variable, but was $h (${h.javaClass})" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/constructors.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/constructors.kt new file mode 100644 index 00000000000..086b5396745 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/constructors.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +class A(d: Double, s: String, parent: A?) { + class Nested(a: A) + inner class Inner(nested: Nested) +} + +fun box(): String { + assertEquals(listOf(java.lang.Double.TYPE, String::class.java, A::class.java), ::A.parameters.map { it.type.javaType }) + assertEquals(listOf(A::class.java), A::Nested.parameters.map { it.type.javaType }) + assertEquals(listOf(A::class.java, A.Nested::class.java), A::Inner.parameters.map { it.type.javaType }) + + assertEquals(A::class.java, ::A.returnType.javaType) + assertEquals(A.Nested::class.java, A::Nested.returnType.javaType) + assertEquals(A.Inner::class.java, A::Inner.returnType.javaType) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/genericArrayElementType.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/genericArrayElementType.kt new file mode 100644 index 00000000000..98550ab6684 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/genericArrayElementType.kt @@ -0,0 +1,37 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FULL_JDK + +import java.lang.reflect.ParameterizedType +import kotlin.reflect.jvm.javaType +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class Bar +fun arrayOfInvBar(): Array = null!! +fun arrayOfInBar(): Array = null!! +fun arrayOfOutBar(): Array = null!! + +fun arrayOfInvList(): Array> = null!! +fun arrayOfInList(): Array> = null!! +fun arrayOfOutList(): Array> = null!! + +fun box(): String { + // NB: in "Array", Java type of X is always Any::class.java because this is the JVM signature generated by the compiler + + assertEquals(Bar::class.java, ::arrayOfInvBar.returnType.arguments.single().type!!.javaType) + assertEquals(Any::class.java, ::arrayOfInBar.returnType.arguments.single().type!!.javaType) + assertEquals(Bar::class.java, ::arrayOfOutBar.returnType.arguments.single().type!!.javaType) + + val invList = ::arrayOfInvList.returnType.arguments.single().type!!.javaType + assertTrue(invList is ParameterizedType && invList.rawType == List::class.java, invList.toString()) + + assertEquals(Any::class.java, ::arrayOfInList.returnType.arguments.single().type!!.javaType) + + val outList = ::arrayOfOutList.returnType.arguments.single().type!!.javaType + assertTrue(outList is ParameterizedType && outList.rawType == List::class.java, outList.toString()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/innerGenericTypeArgument.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/innerGenericTypeArgument.kt new file mode 100644 index 00000000000..70cd78b671f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/innerGenericTypeArgument.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.javaType +import kotlin.test.assertEquals + +class Outer { + inner class Inner { + inner class Innermost + } +} + +fun foo(): Outer.Inner.Innermost = null!! + +fun box(): String { + assertEquals( + listOf( + Any::class.java, + Any::class.java, + String::class.java, + Float::class.javaObjectType, + Int::class.javaObjectType, + Number::class.java + ), + ::foo.returnType.arguments.map { it.type!!.javaType } + ) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/memberFunctions.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/memberFunctions.kt new file mode 100644 index 00000000000..ed54958ed69 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/memberFunctions.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.javaType +import kotlin.test.assertEquals + +class A { + fun foo(t: Long?): Long = t!! +} + +object O { + @JvmStatic + fun bar(a: A): String = "" +} + +fun box(): String { + val foo = A::foo + assertEquals(listOf(A::class.java, java.lang.Long::class.java), foo.parameters.map { it.type.javaType }) + assertEquals(java.lang.Long.TYPE, foo.returnType.javaType) + + val bar = O::class.members.single { it.name == "bar" } + assertEquals(listOf(O::class.java, A::class.java), bar.parameters.map { it.type.javaType }) + assertEquals(String::class.java, bar.returnType.javaType) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/overrideAnyWithPrimitive.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/overrideAnyWithPrimitive.kt new file mode 100644 index 00000000000..e8c9abf1f09 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/overrideAnyWithPrimitive.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.* +import kotlin.test.* + +interface I { + fun foo(): Any +} + +class A : I { + override fun foo(): Int = 0 + fun bar(x: Long): Int = x.toInt() +} + +fun box(): String { + assertEquals(Integer::class.java, A::foo.returnType.javaType) + assertNotEquals(Integer.TYPE, A::foo.returnType.javaType) + + assertNotEquals(Integer::class.java, A::bar.returnType.javaType) + assertEquals(Integer.TYPE, A::bar.returnType.javaType) + + assertEquals(java.lang.Long.TYPE, A::bar.parameters.last().type.javaType) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/parameterizedTypeArgument.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/parameterizedTypeArgument.kt new file mode 100644 index 00000000000..e8fbcd5ecd5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/parameterizedTypeArgument.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.javaType +import kotlin.test.assertEquals + +fun listOfStrings(): List = null!! + +class Foo +class Bar +fun fooOfInvBar(): Foo = null!! +fun fooOfInBar(): Foo = null!! +fun fooOfOutBar(): Foo = null!! + +fun box(): String { + assertEquals(String::class.java, ::listOfStrings.returnType.arguments.single().type!!.javaType) + + assertEquals(Bar::class.java, ::fooOfInvBar.returnType.arguments.single().type!!.javaType) + assertEquals(Bar::class.java, ::fooOfInBar.returnType.arguments.single().type!!.javaType) + assertEquals(Bar::class.java, ::fooOfOutBar.returnType.arguments.single().type!!.javaType) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/parameterizedTypes.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/parameterizedTypes.kt new file mode 100644 index 00000000000..73eb30e1239 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/parameterizedTypes.kt @@ -0,0 +1,45 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FULL_JDK + +import java.lang.reflect.ParameterizedType +import kotlin.reflect.* +import kotlin.reflect.jvm.javaType +import kotlin.test.assertEquals + +class A(private var foo: List) + +object O { + @JvmStatic + private var bar: List = listOf() +} + +fun topLevel(): List = listOf() +fun Any.extension(): List = listOf() + +fun assertGenericType(type: KType) { + val javaType = type.javaType + if (javaType !is ParameterizedType) { + throw AssertionError("Type should be a parameterized type, but was $javaType (${javaType.javaClass})") + } +} + +fun box(): String { + val foo = A::class.members.single { it.name == "foo" } as KMutableProperty<*> + assertGenericType(foo.returnType) + assertGenericType(foo.getter.returnType) + assertGenericType(foo.setter.parameters.last().type) + + val bar = O::class.members.single { it.name == "bar" } as KMutableProperty<*> + assertGenericType(bar.returnType) + assertGenericType(bar.getter.returnType) + assertGenericType(bar.setter.parameters.last().type) + + assertGenericType(::topLevel.returnType) + assertGenericType(Any::extension.returnType) + assertGenericType(::A.parameters.single().type) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/propertyAccessors.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/propertyAccessors.kt new file mode 100644 index 00000000000..b99ffe69cd3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/propertyAccessors.kt @@ -0,0 +1,29 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KMutableProperty +import kotlin.reflect.jvm.javaType +import kotlin.test.assertEquals + +class A(private var foo: String) + +object O { + @JvmStatic + private var bar: String = "" +} + +fun box(): String { + val foo = A::class.members.single { it.name == "foo" } as KMutableProperty<*> + assertEquals(listOf(A::class.java), foo.parameters.map { it.type.javaType }) + assertEquals(listOf(A::class.java), foo.getter.parameters.map { it.type.javaType }) + assertEquals(listOf(A::class.java, String::class.java), foo.setter.parameters.map { it.type.javaType }) + + val bar = O::class.members.single { it.name == "bar" } as KMutableProperty<*> + assertEquals(listOf(O::class.java), bar.parameters.map { it.type.javaType }) + assertEquals(listOf(O::class.java), bar.getter.parameters.map { it.type.javaType }) + assertEquals(listOf(O::class.java, String::class.java), bar.setter.parameters.map { it.type.javaType }) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/rawTypeArgument.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/rawTypeArgument.kt new file mode 100644 index 00000000000..dff36ee7e4e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/rawTypeArgument.kt @@ -0,0 +1,21 @@ +// TARGET_BACKEND: JVM + +// WITH_REFLECT +// FILE: J.java + +import java.util.List; + +public interface J { + List foo(); +} + +// FILE: K.kt + +import kotlin.reflect.jvm.javaType +import kotlin.test.assertEquals + +fun box(): String { + assertEquals(Any::class.java, J::foo.returnType.arguments.single().type!!.javaType) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/supertypes.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/supertypes.kt new file mode 100644 index 00000000000..89e71b9389e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/supertypes.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FULL_JDK + +import java.lang.reflect.ParameterizedType +import java.lang.reflect.TypeVariable +import kotlin.reflect.jvm.javaType +import kotlin.test.assertEquals +import kotlin.test.assertTrue +import kotlin.test.fail + +open class Klass +interface Interface +interface Interface2 + +class A : Interface, Klass(), Interface2 + +fun box(): String { + val (i, k, i2) = A::class.supertypes.map { it.javaType } + + i as? ParameterizedType ?: fail("Not a parameterized type: $i") + assertEquals(Interface::class.java, i.rawType) + val args = i.actualTypeArguments + assertEquals(String::class.java, args[0], "Not String: ${args[0]}") + assertTrue(args[1].let { it is TypeVariable<*> && it.name == "Z" && it.genericDeclaration == A::class.java }, "Not Z: ${args[1]}") + + assertEquals(Klass::class.java, k) + + assertEquals(Interface2::class.java, i2) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/topLevelFunctions.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/topLevelFunctions.kt new file mode 100644 index 00000000000..fe4dbc71e2b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/topLevelFunctions.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +fun free(s: String): Int = s.length + +fun Any.extension() {} + +fun box(): String { + assertEquals(java.lang.Integer.TYPE, ::free.returnType.javaType) + assertEquals(String::class.java, ::free.parameters.single().type.javaType) + + assertEquals(Any::class.java, Any::extension.parameters.single().type.javaType) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/typeParameters.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/typeParameters.kt new file mode 100644 index 00000000000..7ca39047f7c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/typeParameters.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FULL_JDK + +import java.lang.reflect.TypeVariable +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +class A { + fun foo(t: T) {} +} + +fun box(): String { + val f = A::foo + val t = f.parameters.last().type.javaType + if (t !is TypeVariable<*>) return "Fail, t should be a type variable: $t" + + assertEquals("T", t.name) + assertEquals("A", (t.genericDeclaration as Class<*>).name) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/unit.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/unit.kt new file mode 100644 index 00000000000..2b4d8327986 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/unit.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +fun foo(unitParam: Unit, nullableUnitParam: Unit?): Unit {} + +var bar: Unit = Unit + +fun box(): String { + assert(Unit::class.java != java.lang.Void.TYPE) + + assertEquals(Unit::class.java, ::foo.parameters[0].type.javaType) + assertEquals(Unit::class.java, ::foo.parameters[1].type.javaType) + assertEquals(java.lang.Void.TYPE, ::foo.returnType.javaType) + + assertEquals(Unit::class.java, ::bar.returnType.javaType) + assertEquals(Unit::class.java, ::bar.getter.returnType.javaType) + assertEquals(Unit::class.java, ::bar.setter.parameters.single().type.javaType) + assertEquals(java.lang.Void.TYPE, ::bar.setter.returnType.javaType) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/withNullability.kt b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/withNullability.kt new file mode 100644 index 00000000000..a51b0843471 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/mapping/types/withNullability.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.full.withNullability +import kotlin.reflect.jvm.javaType +import kotlin.test.assertEquals + +fun nonNull(): String = "" +fun nullable(): String? = "" + +fun box(): String { + val nonNull = ::nonNull.returnType + val nullable = ::nullable.returnType + + assertEquals(nullable.javaType, nullable.withNullability(false).javaType) + assertEquals(nullable.javaType, nullable.withNullability(true).javaType) + assertEquals(nonNull.javaType, nonNull.withNullability(false).javaType) + assertEquals(nullable.javaType, nonNull.withNullability(true).javaType) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/callableReferencesEqualToCallablesFromAPI.kt b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/callableReferencesEqualToCallablesFromAPI.kt new file mode 100644 index 00000000000..6aed0593328 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/callableReferencesEqualToCallablesFromAPI.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.test.assertEquals + +class A { + fun foo() = "foo" + val bar = "bar" +} + +fun checkEqual(x: Any, y: Any) { + assertEquals(x, y) + assertEquals(y, x) + assertEquals(x.hashCode(), y.hashCode()) +} + +fun box(): String { + checkEqual(A::foo, A::class.members.single { it.name == "foo" }) + checkEqual(A::bar, A::class.members.single { it.name == "bar" }) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/classToString.kt b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/classToString.kt new file mode 100644 index 00000000000..3dce944568e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/classToString.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.* + +class A { + class Nested + + companion object +} + +fun box(): String { + assertEquals("class A", "${A::class}") + assertEquals("class A\$Nested", "${A.Nested::class}") + assertEquals("class A\$Companion", "${A.Companion::class}") + + assertEquals("class kotlin.Any", "${Any::class}") + assertEquals("class kotlin.Int", "${Int::class}") + assertEquals("class kotlin.Int\$Companion", "${Int.Companion::class}") + assertEquals("class kotlin.IntArray", "${IntArray::class}") + assertEquals("class kotlin.String", "${String::class}") + assertEquals("class kotlin.String", "${java.lang.String::class}") + + assertEquals("class kotlin.Array", "${Array::class}") + assertEquals("class kotlin.Array", "${Array::class}") + assertEquals("class kotlin.Array", "${Array>::class}") + + assertEquals("class java.lang.Runnable", "${Runnable::class}") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/extensionPropertyReceiverToString.kt b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/extensionPropertyReceiverToString.kt new file mode 100644 index 00000000000..c7d0be37e3b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/extensionPropertyReceiverToString.kt @@ -0,0 +1,91 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KProperty1 +import kotlin.test.assertEquals + +fun check(expected: String, p: KProperty1<*, *>) { + var s = p.toString() + + // Strip "val" or "var" + assert(s.startsWith("val ") || s.startsWith("var ")) { "Fail val/var: $s" } + s = s.substring(4) + + // Strip property type + s = s.substringBeforeLast(':') + + // Strip property name, leave only receiver class + s = s.substringBeforeLast('.') + + assertEquals(expected, s) +} + +val Boolean.x: Any get() = this +val Char.x: Any get() = this +val Byte.x: Any get() = this +val Short.x: Any get() = this +val Int.x: Any get() = this +val Float.x: Any get() = this +val Long.x: Any get() = this +val Double.x: Any get() = this + +val BooleanArray.x: Any get() = this +val CharArray.x: Any get() = this +val ByteArray.x: Any get() = this +val ShortArray.x: Any get() = this +val IntArray.x: Any get() = this +val FloatArray.x: Any get() = this +val LongArray.x: Any get() = this +val DoubleArray.x: Any get() = this + +val Array.a1: Any get() = this +val Array.a2: Any get() = this +val Array>.a3: Any get() = this +val Array.a4: Any get() = this + +val Any?.n1: Any get() = Any() +val Int?.n2: Any get() = Any() +val Array?.n3: Any get() = Any() +val Array.n4: Any get() = Any() +val Array?.n5: Any get() = Any() + +val Map.m: Any get() = this +val List>>.l: Any get() = this + +fun box(): String { + check("kotlin.Boolean", Boolean::x) + check("kotlin.Char", Char::x) + check("kotlin.Byte", Byte::x) + check("kotlin.Short", Short::x) + check("kotlin.Int", Int::x) + check("kotlin.Float", Float::x) + check("kotlin.Long", Long::x) + check("kotlin.Double", Double::x) + + check("kotlin.BooleanArray", BooleanArray::x) + check("kotlin.CharArray", CharArray::x) + check("kotlin.ByteArray", ByteArray::x) + check("kotlin.ShortArray", ShortArray::x) + check("kotlin.IntArray", IntArray::x) + check("kotlin.FloatArray", FloatArray::x) + check("kotlin.LongArray", LongArray::x) + check("kotlin.DoubleArray", DoubleArray::x) + + check("kotlin.Any?", Any?::n1) + check("kotlin.Int?", Int?::n2) + check("kotlin.Array?", Array?::n3) + check("kotlin.Array", Array::n4) + check("kotlin.Array?", Array?::n5) + + check("kotlin.Array", Array::a1) + check("kotlin.Array", Array::a2) + check("kotlin.Array>", Array>::a3) + check("kotlin.Array", Array::a4) + + check("kotlin.collections.Map", Map::m) + check("kotlin.collections.List>>", List>>::l) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/functionEqualsHashCode.kt b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/functionEqualsHashCode.kt new file mode 100644 index 00000000000..72b169fe9fb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/functionEqualsHashCode.kt @@ -0,0 +1,36 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.* + +fun top() = 42 + +fun Int.intExt(): Int = this + +class A { + fun mem() {} +} + +class B { + fun mem() {} +} + + +fun checkEqual(x: Any, y: Any) { + assertEquals(x, y) + assertEquals(x.hashCode(), y.hashCode(), "Elements are equal but their hash codes are not: ${x.hashCode()} != ${y.hashCode()}") +} + +fun box(): String { + checkEqual(::top, ::top) + checkEqual(Int::intExt, Int::intExt) + checkEqual(A::mem, A::mem) + + assertFalse(::top == Int::intExt) + assertFalse(::top == A::mem) + assertFalse(A::mem == B::mem) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/functionToString.kt b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/functionToString.kt new file mode 100644 index 00000000000..dec835773dc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/functionToString.kt @@ -0,0 +1,29 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +package test + +import kotlin.test.assertEquals + +fun top() = 42 + +fun String.ext(): Int = 0 +fun IntRange?.ext2(): Array = arrayOfNulls(0) + +class A { + fun mem(): String = "" +} + +fun assertToString(s: String, x: Any) { + assertEquals(s, x.toString()) +} + +fun box(): String { + assertToString("fun top(): kotlin.Int", ::top) + assertToString("fun kotlin.String.ext(): kotlin.Int", String::ext) + assertToString("fun kotlin.ranges.IntRange?.ext2(): kotlin.Array", IntRange::ext2) + assertToString("fun test.A.mem(): kotlin.String", A::mem) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/memberExtensionToString.kt b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/memberExtensionToString.kt new file mode 100644 index 00000000000..1fe66891efa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/memberExtensionToString.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* + +class A { + var String.id: String + get() = this + set(value) {} + + fun Int.foo(): Double = toDouble() +} + +fun box(): String { + val p = A::class.java.kotlin.memberExtensionProperties.single() + return if ("$p" == "var A.(kotlin.String.)id: kotlin.String") "OK" else "Fail $p" + + val q = A::class.java.kotlin.declaredFunctions.single() + if ("$q" != "fun A.(kotlin.Int.)foo(): kotlin.Double") return "Fail q $q" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/parametersEqualsHashCode.kt b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/parametersEqualsHashCode.kt new file mode 100644 index 00000000000..79ea783e548 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/parametersEqualsHashCode.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.* + +class A { + fun foo(s: String, x: Int) {} + fun bar(x: Int) {} + val baz = 42 +} + +fun box(): String { + // Dispatch receiver parameters of different callables are not equal + assertNotEquals(A::foo.parameters[0], A::bar.parameters[0]) + assertNotEquals(A::foo.parameters[0], A::baz.parameters[0]) + + assertNotEquals(A::foo.parameters[1], A::bar.parameters[1]) + assertNotEquals(A::foo.parameters[1], A::foo.parameters[2]) + assertNotEquals(A::bar.parameters[1], A::foo.parameters[2]) + + assertEquals(A::foo.parameters[0], A::foo.parameters[0]) + assertEquals(A::foo.parameters[0].hashCode(), A::foo.parameters[0].hashCode()) + assertEquals(A::foo.parameters[1], A::foo.parameters[1]) + assertEquals(A::foo.parameters[1].hashCode(), A::foo.parameters[1].hashCode()) + assertEquals(A::bar.parameters[0], A::bar.parameters[0]) + assertEquals(A::bar.parameters[0].hashCode(), A::bar.parameters[0].hashCode()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/parametersToString.kt b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/parametersToString.kt new file mode 100644 index 00000000000..fa186eef7b5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/parametersToString.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.* + +fun Int.foo(s: String) {} + +class A { + fun bar() {} +} + +fun baz(name: String) {} + +fun box(): String { + assertEquals( + listOf("extension receiver of ${Int::foo}", "parameter #1 s of ${Int::foo}"), + Int::foo.parameters.map(Any::toString) + ) + + assertEquals( + listOf("instance of ${A::bar}"), + A::bar.parameters.map(Any::toString) + ) + + assertEquals( + listOf("parameter #0 name of ${::baz}"), + ::baz.parameters.map(Any::toString) + ) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/propertyEqualsHashCode.kt b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/propertyEqualsHashCode.kt new file mode 100644 index 00000000000..4d2affbd96b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/propertyEqualsHashCode.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.* + +val top = 42 +var top2 = -23 + +val Int.intExt: Int get() = this +val Char.charExt: Int get() = this.toInt() + +class A(var mem: String) +class B(var mem: String) + + +fun checkEqual(x: Any, y: Any) { + assertEquals(x, y) + assertEquals(x.hashCode(), y.hashCode(), "Elements are equal but their hash codes are not: ${x.hashCode()} != ${y.hashCode()}") +} + +fun box(): String { + checkEqual(::top, ::top) + checkEqual(::top2, ::top2) + checkEqual(Int::intExt, Int::intExt) + checkEqual(A::mem, A::mem) + + assertFalse(::top == ::top2) + assertFalse(Int::intExt == Char::charExt) + assertFalse(A::mem == B::mem) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/propertyToString.kt b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/propertyToString.kt new file mode 100644 index 00000000000..4290f008a42 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/propertyToString.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +package test + +import kotlin.test.assertEquals + +val top = 42 +var top2 = -23 + +val String.ext: Int get() = 0 +var IntRange?.ext2: Int get() = 0; set(value) {} + +class A(val mem: String) +class B(var mem: String) + +fun assertToString(s: String, x: Any) { + assertEquals(s, x.toString()) +} + +fun box(): String { + assertToString("val top: kotlin.Int", ::top) + assertToString("var top2: kotlin.Int", ::top2) + assertToString("val kotlin.String.ext: kotlin.Int", String::ext) + assertToString("var kotlin.ranges.IntRange?.ext2: kotlin.Int", IntRange::ext2) + assertToString("val test.A.mem: kotlin.String", A::mem) + assertToString("var test.B.mem: kotlin.String", B::mem) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/typeEqualsHashCode.kt b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/typeEqualsHashCode.kt new file mode 100644 index 00000000000..34d8104179e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/typeEqualsHashCode.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KType +import kotlin.test.assertEquals +import kotlin.test.assertNotEquals + +fun unit(p: Unit): Unit {} + +fun nullable(s: String): String? = s + +class A { + fun typeParam(t: T): T = t +} + + +fun box(): String { + fun check(t1: KType, t2: KType) { + assertEquals(t1, t2) + assertEquals(t1.hashCode(), t2.hashCode()) + } + + check(::unit.parameters.single().type, ::unit.returnType) + + assertNotEquals(::nullable.parameters.single().type, ::nullable.returnType) + + val typeParam = A::class.members.single { it.name == "typeParam" } + check(typeParam.parameters.last().type, typeParam.returnType) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/typeParametersEqualsHashCode.kt b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/typeParametersEqualsHashCode.kt new file mode 100644 index 00000000000..5c8207fe492 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/typeParametersEqualsHashCode.kt @@ -0,0 +1,42 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals +import kotlin.test.assertNotEquals + +class A +class B + +class Fun { + fun foo(): T = null!! +} + +class Fourple + +fun box(): String { + assertEquals(A::class.typeParameters, A::class.typeParameters) + assertEquals(A::class.typeParameters.single().hashCode(), A::class.typeParameters.single().hashCode()) + + fun getFoo() = Fun::class.members.single { it.name == "foo" } + assertEquals(getFoo().typeParameters, getFoo().typeParameters) + assertEquals(getFoo().typeParameters.single().hashCode(), getFoo().typeParameters.single().hashCode()) + + assertNotEquals(A::class.typeParameters.single(), B::class.typeParameters.single()) + + val fi = Fourple::class.typeParameters + val fj = Fourple::class.typeParameters + for (i in 0..fi.size - 1) { + for (j in 0..fj.size - 1) { + if (i == j) { + assertEquals(fi[i], fj[j]) + assertEquals(fi[i].hashCode(), fj[j].hashCode()) + } else { + assertNotEquals(fi[i], fj[j]) + } + } + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/typeParametersToString.kt b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/typeParametersToString.kt new file mode 100644 index 00000000000..69adf928177 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/typeParametersToString.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +interface Variance +class OneBound> +class SeveralBounds where T : Enum, T : Variance + +fun box(): String { + assertEquals("[A, in B, out C, D]", Variance::class.typeParameters.toString()) + assertEquals("[T]", OneBound::class.typeParameters.toString()) + assertEquals("[T]", SeveralBounds::class.typeParameters.toString()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/typeToString.kt b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/typeToString.kt new file mode 100644 index 00000000000..805f4d8438b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/typeToString.kt @@ -0,0 +1,40 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +fun String?.foo(x: Int, y: Array, z: IntArray, w: List>>) {} + +class A { + fun bar(t: T, u: U): T? = null +} + +fun baz(inProjection: A, outProjection: A) {} + +fun box(): String { + assertEquals( + listOf( + "kotlin.String?", + "kotlin.Int", + "kotlin.Array", + "kotlin.IntArray", + "kotlin.collections.List>>" + ), + String?::foo.parameters.map { it.type.toString() } + ) + + assertEquals("kotlin.Unit", String?::foo.returnType.toString()) + + val bar = A::class.members.single { it.name == "bar" } + assertEquals(listOf("A", "T", "U"), bar.parameters.map { it.type.toString() }) + assertEquals("T?", bar.returnType.toString()) + + assertEquals( + listOf("A", "A"), + ::baz.parameters.map { it.type.toString() } + ) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/typeToStringInnerGeneric.kt b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/typeToStringInnerGeneric.kt new file mode 100644 index 00000000000..da6d846e8f5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/methodsFromAny/typeToStringInnerGeneric.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +class A { + inner class B { + inner class C + } +} + +fun foo(): A.B.C = null!! + +fun box(): String { + assertEquals("A.B.C", ::foo.returnType.toString()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/modifiers/callableModality.kt b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/callableModality.kt new file mode 100644 index 00000000000..e75ac5d3149 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/callableModality.kt @@ -0,0 +1,54 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertTrue +import kotlin.test.assertFalse + +interface Interface { + open fun openFun() {} + abstract fun abstractFun() +} + +abstract class AbstractClass { + final val finalVal = Unit + open val openVal = Unit + abstract var abstractVar: Unit +} + +fun box(): String { + assertFalse(Interface::openFun.isFinal) + assertTrue(Interface::openFun.isOpen) + assertFalse(Interface::openFun.isAbstract) + + assertFalse(Interface::abstractFun.isFinal) + assertFalse(Interface::abstractFun.isOpen) + assertTrue(Interface::abstractFun.isAbstract) + + assertTrue(AbstractClass::finalVal.isFinal) + assertFalse(AbstractClass::finalVal.isOpen) + assertFalse(AbstractClass::finalVal.isAbstract) + assertTrue(AbstractClass::finalVal.getter.isFinal) + assertFalse(AbstractClass::finalVal.getter.isOpen) + assertFalse(AbstractClass::finalVal.getter.isAbstract) + + assertFalse(AbstractClass::openVal.isFinal) + assertTrue(AbstractClass::openVal.isOpen) + assertFalse(AbstractClass::openVal.isAbstract) + assertFalse(AbstractClass::openVal.getter.isFinal) + assertTrue(AbstractClass::openVal.getter.isOpen) + assertFalse(AbstractClass::openVal.getter.isAbstract) + + assertFalse(AbstractClass::abstractVar.isFinal) + assertFalse(AbstractClass::abstractVar.isOpen) + assertTrue(AbstractClass::abstractVar.isAbstract) + assertFalse(AbstractClass::abstractVar.getter.isFinal) + assertFalse(AbstractClass::abstractVar.getter.isOpen) + assertTrue(AbstractClass::abstractVar.getter.isAbstract) + assertFalse(AbstractClass::abstractVar.setter.isFinal) + assertFalse(AbstractClass::abstractVar.setter.isOpen) + assertTrue(AbstractClass::abstractVar.setter.isAbstract) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/modifiers/callableVisibility.kt b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/callableVisibility.kt new file mode 100644 index 00000000000..40dd01f4b03 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/callableVisibility.kt @@ -0,0 +1,58 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KFunction +import kotlin.reflect.KProperty +import kotlin.reflect.KVisibility +import kotlin.test.assertEquals + +open class Foo { + public fun publicFun() {} + protected fun protectedFun() {} + internal fun internalFun() {} + private fun privateFun() {} + private fun privateToThisFun(): T = null!! + + fun getProtectedFun() = this::protectedFun + fun getPrivateFun() = this::privateFun + fun getPrivateToThisFun(): KFunction<*> = this::privateToThisFun + + public val publicVal = Unit + protected val protectedVar = Unit + internal val internalVal = Unit + private val privateVal = Unit + private val privateToThisVal: T? = null + + fun getProtectedVar() = this::protectedVar + fun getPrivateVal() = this::privateVal + fun getPrivateToThisVal(): KProperty<*> = this::privateToThisVal + + public var publicVarPrivateSetter = Unit + private set + + fun getPublicVarPrivateSetter() = this::publicVarPrivateSetter +} + +fun box(): String { + val f = Foo() + + assertEquals(KVisibility.PUBLIC, f::publicFun.visibility) + assertEquals(KVisibility.PROTECTED, f.getProtectedFun().visibility) + assertEquals(KVisibility.INTERNAL, f::internalFun.visibility) + assertEquals(KVisibility.PRIVATE, f.getPrivateFun().visibility) + assertEquals(KVisibility.PRIVATE, f.getPrivateToThisFun().visibility) + + assertEquals(KVisibility.PUBLIC, f::publicVal.visibility) + assertEquals(KVisibility.PROTECTED, f.getProtectedVar().visibility) + assertEquals(KVisibility.INTERNAL, f::internalVal.visibility) + assertEquals(KVisibility.PRIVATE, f.getPrivateVal().visibility) + assertEquals(KVisibility.PRIVATE, f.getPrivateToThisVal().visibility) + + assertEquals(KVisibility.PUBLIC, f.getPublicVarPrivateSetter().visibility) + assertEquals(KVisibility.PUBLIC, f.getPublicVarPrivateSetter().getter.visibility) + assertEquals(KVisibility.PRIVATE, f.getPublicVarPrivateSetter().setter.visibility) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/modifiers/classModality.kt b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/classModality.kt new file mode 100644 index 00000000000..d3e2dd721dd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/classModality.kt @@ -0,0 +1,59 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertTrue +import kotlin.test.assertFalse + +class FinalClass { + companion object Companion +} +open class OpenClass +abstract class AbstractClass +interface Interface +enum class EnumClass +enum class EnumClassWithAbstractMember { ; abstract fun foo() } +annotation class AnnotationClass +object Object + +fun box(): String { + assertTrue(FinalClass::class.isFinal) + assertFalse(FinalClass::class.isOpen) + assertFalse(FinalClass::class.isAbstract) + + assertTrue(FinalClass.Companion::class.isFinal) + assertFalse(FinalClass.Companion::class.isOpen) + assertFalse(FinalClass.Companion::class.isAbstract) + + assertFalse(OpenClass::class.isFinal) + assertTrue(OpenClass::class.isOpen) + assertFalse(OpenClass::class.isAbstract) + + assertFalse(AbstractClass::class.isFinal) + assertFalse(AbstractClass::class.isOpen) + assertTrue(AbstractClass::class.isAbstract) + + assertFalse(Interface::class.isFinal) + assertFalse(Interface::class.isOpen) + assertTrue(Interface::class.isAbstract) + + assertTrue(EnumClass::class.isFinal) + assertFalse(EnumClass::class.isOpen) + assertFalse(EnumClass::class.isAbstract) + + assertTrue(EnumClassWithAbstractMember::class.isFinal) + assertFalse(EnumClassWithAbstractMember::class.isOpen) + assertFalse(EnumClassWithAbstractMember::class.isAbstract) + + // Note that unlike in JVM, annotation classes are final in Kotlin + assertTrue(AnnotationClass::class.isFinal) + assertFalse(AnnotationClass::class.isOpen) + assertFalse(AnnotationClass::class.isAbstract) + + assertTrue(Object::class.isFinal) + assertFalse(Object::class.isOpen) + assertFalse(Object::class.isAbstract) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/modifiers/classVisibility.kt b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/classVisibility.kt new file mode 100644 index 00000000000..661d5081478 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/classVisibility.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KClass +import kotlin.reflect.KVisibility +import kotlin.test.assertEquals + +class DefaultVisibilityClass +public class PublicClass { + protected class ProtectedClass + fun getProtectedClass(): KClass<*> = ProtectedClass::class +} +internal class InternalClass +private class PrivateClass + +fun box(): String { + assertEquals(KVisibility.PUBLIC, DefaultVisibilityClass::class.visibility) + assertEquals(KVisibility.PUBLIC, PublicClass::class.visibility) + assertEquals(KVisibility.PROTECTED, PublicClass().getProtectedClass().visibility) + assertEquals(KVisibility.INTERNAL, InternalClass::class.visibility) + assertEquals(KVisibility.PRIVATE, PrivateClass::class.visibility) + + class Local + assertEquals(null, Local::class.visibility) + + val anonymous = object {} + assertEquals(null, anonymous::class.visibility) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/modifiers/classes.kt b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/classes.kt new file mode 100644 index 00000000000..1febcc0ce33 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/classes.kt @@ -0,0 +1,46 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertTrue +import kotlin.test.assertFalse + +sealed class S { + data class DataClass(val x: Int) : S() + inner class InnerClass + companion object + object NonCompanionObject +} + +fun box(): String { + assertTrue(S::class.isSealed) + assertFalse(S::class.isFinal) + assertFalse(S::class.isOpen) + assertFalse(S::class.isAbstract) + assertFalse(S::class.isData) + assertFalse(S::class.isInner) + assertFalse(S::class.isCompanion) + + assertFalse(S.DataClass::class.isSealed) + assertTrue(S.DataClass::class.isData) + assertFalse(S.DataClass::class.isInner) + assertFalse(S.DataClass::class.isCompanion) + + assertFalse(S.InnerClass::class.isSealed) + assertFalse(S.InnerClass::class.isData) + assertTrue(S.InnerClass::class.isInner) + assertFalse(S.InnerClass::class.isCompanion) + + assertFalse(S.Companion::class.isSealed) + assertFalse(S.Companion::class.isData) + assertFalse(S.Companion::class.isInner) + assertTrue(S.Companion::class.isCompanion) + + assertFalse(S.NonCompanionObject::class.isSealed) + assertFalse(S.NonCompanionObject::class.isData) + assertFalse(S.NonCompanionObject::class.isInner) + assertFalse(S.NonCompanionObject::class.isCompanion) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/modifiers/functions.kt b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/functions.kt new file mode 100644 index 00000000000..8a9372217f5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/functions.kt @@ -0,0 +1,62 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertTrue +import kotlin.test.assertFalse + +inline fun inline() {} +class External { external fun external() } +operator fun Unit.invoke() {} +infix fun Unit.infix(unit: Unit) {} +// TODO: support or prohibit references to suspend functions +// class Suspend { suspend fun suspend(c: Continuation) {} } + +val externalGetter = Unit + external get + +inline var inlineProperty: Unit + get() = Unit + set(value) {} + +fun box(): String { + assertTrue(::inline.isInline) + assertFalse(::inline.isExternal) + assertFalse(::inline.isOperator) + assertFalse(::inline.isInfix) + assertFalse(::inline.isSuspend) + + assertFalse(External::external.isInline) + assertTrue(External::external.isExternal) + assertFalse(External::external.isOperator) + assertFalse(External::external.isInfix) + assertFalse(External::external.isSuspend) + + assertFalse(Unit::invoke.isInline) + assertFalse(Unit::invoke.isExternal) + assertTrue(Unit::invoke.isOperator) + assertFalse(Unit::invoke.isInfix) + assertFalse(Unit::invoke.isSuspend) + + assertFalse(Unit::infix.isInline) + assertFalse(Unit::infix.isExternal) + assertFalse(Unit::infix.isOperator) + assertTrue(Unit::infix.isInfix) + assertFalse(Unit::infix.isSuspend) + +// assertFalse(Suspend::suspend.isInline) +// assertFalse(Suspend::suspend.isExternal) +// assertFalse(Suspend::suspend.isOperator) +// assertFalse(Suspend::suspend.isInfix) +// assertTrue(Suspend::suspend.isSuspend) + + assertTrue(::externalGetter.getter.isExternal) + assertFalse(::externalGetter.getter.isInline) + + assertFalse(::inlineProperty.getter.isExternal) + assertTrue(::inlineProperty.getter.isInline) + assertTrue(::inlineProperty.setter.isInline) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/modifiers/javaVisibility.kt b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/javaVisibility.kt new file mode 100644 index 00000000000..d0508d4d841 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/javaVisibility.kt @@ -0,0 +1,36 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +class J { + protected class C {} + protected static class D {} + + void foo() {} + protected void bar() {} + protected static void baz() {} +} + +// FILE: K.kt + +import kotlin.test.assertEquals + +fun box(): String { + // Package-private class + assertEquals(null, J::class.visibility) + // Protected+package class + assertEquals(null, J.C::class.visibility) + // Protected static class + assertEquals(null, J.D::class.visibility) + + // Package-private method + assertEquals(null, J::foo.visibility) + // Protected+package method + assertEquals(null, J::bar.visibility) + // Protected static method + assertEquals(null, J::baz.visibility) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/modifiers/properties.kt b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/properties.kt new file mode 100644 index 00000000000..24711c80d9a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/properties.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertTrue +import kotlin.test.assertFalse + +const val const = "const" +val nonConst = "nonConst" + +class A { + lateinit var lateinit: Unit + var nonLateinit = Unit +} + +fun box(): String { + assertTrue(::const.isConst) + assertFalse(::nonConst.isConst) + + assertTrue(A::lateinit.isLateinit) + assertFalse(A::nonLateinit.isLateinit) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/modifiers/typeParameters.kt b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/typeParameters.kt new file mode 100644 index 00000000000..486fed08f81 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/modifiers/typeParameters.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertTrue +import kotlin.test.assertFalse + +class A { + fun nonReified(): T = null!! + inline fun reified(): U = null!! +} + +fun box(): String { + assertFalse(A::class.members.single { it.name == "nonReified" }.typeParameters.single().isReified) + assertTrue(A::class.members.single { it.name == "reified" }.typeParameters.single().isReified) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/multifileClasses/callFunctionsInMultifileClass.kt b/backend.native/tests/external/codegen/blackbox/reflection/multifileClasses/callFunctionsInMultifileClass.kt new file mode 100644 index 00000000000..682f33e92f1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/multifileClasses/callFunctionsInMultifileClass.kt @@ -0,0 +1,35 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: Test1.kt + +@file:kotlin.jvm.JvmName("Test") +@file:kotlin.jvm.JvmMultifileClass +package test + +import kotlin.test.assertEquals + +fun getX() = 1 + +fun box(): String { + assertEquals("getX", ::getX.name) + assertEquals("getY", ::getY.name) + assertEquals("getZ", ::getZ.name) + + assertEquals(1, ::getX.call()) + assertEquals(239, ::getY.call()) + assertEquals(42, ::getZ.callBy(emptyMap())) + + return "OK" +} + +// FILE: Test2.kt + +@file:kotlin.jvm.JvmName("Test") +@file:kotlin.jvm.JvmMultifileClass +package test + +fun getY() = 239 + +fun getZ(value: Int = 42) = value diff --git a/backend.native/tests/external/codegen/blackbox/reflection/multifileClasses/callPropertiesInMultifileClass.kt b/backend.native/tests/external/codegen/blackbox/reflection/multifileClasses/callPropertiesInMultifileClass.kt new file mode 100644 index 00000000000..44e0b439f7f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/multifileClasses/callPropertiesInMultifileClass.kt @@ -0,0 +1,45 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// KT-11447 Multifile declaration causes IAE: Method can not access a member of class +// WITH_REFLECT +// FILE: Test1.kt + +@file:kotlin.jvm.JvmName("Test") +@file:kotlin.jvm.JvmMultifileClass +package test + +import kotlin.test.assertEquals + +var x = 1 + +fun box(): String { + assertEquals("x", ::x.name) + assertEquals("y", ::y.name) + assertEquals("MAGIC_NUMBER", ::MAGIC_NUMBER.name) + + assertEquals(1, ::x.call()) + assertEquals(1, ::x.getter.call()) + + assertEquals(239, ::y.call()) + assertEquals(239, ::y.getter.call()) + + assertEquals(42, ::MAGIC_NUMBER.call()) + assertEquals(42, ::MAGIC_NUMBER.getter.call()) + + assertEquals(Unit, ::x.setter.call(2)) + assertEquals(2, ::x.call()) + assertEquals(2, ::x.getter.call()) + + return "OK" +} + +// FILE: Test2.kt + +@file:kotlin.jvm.JvmName("Test") +@file:kotlin.jvm.JvmMultifileClass +package test + +val y = 239 + +const val MAGIC_NUMBER = 42 diff --git a/backend.native/tests/external/codegen/blackbox/reflection/multifileClasses/javaFieldForVarAndConstVal.kt b/backend.native/tests/external/codegen/blackbox/reflection/multifileClasses/javaFieldForVarAndConstVal.kt new file mode 100644 index 00000000000..b992742377c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/multifileClasses/javaFieldForVarAndConstVal.kt @@ -0,0 +1,75 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FULL_JDK +// FILE: 1.kt + +@file:kotlin.jvm.JvmName("Test") +@file:kotlin.jvm.JvmMultifileClass +package test + +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +fun testX() { + val field = ::x.javaField ?: throw AssertionError("No java field for ${::x.name}") + + try { + field.get(null) + throw AssertionError("Fail: field.get should fail because the field is private") + } + catch (e: IllegalAccessException) { + // OK + } + + field.setAccessible(true) + assertEquals("I am x", field.get(null)) + field.set(null, "OK") +} + +fun testY() { + val field = ::y.javaField ?: throw AssertionError("No java field for ${::y.name}") + + assertEquals("I am const y", field.get(null)) + + // Accessible = false should have no effect because the field is public + field.setAccessible(false) + + assertEquals("I am const y", field.get(null)) +} + +fun testZ() { + val field = refZ.javaField ?: throw AssertionError("No java field for ${refZ.name}") + + + try { + field.get(null) + throw AssertionError("IllegalAccessError expected") + } + catch (e: IllegalAccessException) { + // OK + } + + field.setAccessible(true) + assertEquals("I am private const val Z", field.get(null)) +} + +fun box(): String { + testX() + testY() + testZ() + return x +} + +// FILE: 2.kt + +@file:kotlin.jvm.JvmName("Test") +@file:kotlin.jvm.JvmMultifileClass +package test + +var x = "I am x" +const val y = "I am const y" +private const val z = "I am private const val Z" + +val refZ = ::z \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/javaClass.kt b/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/javaClass.kt new file mode 100644 index 00000000000..6284db2f30f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/javaClass.kt @@ -0,0 +1,36 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.* + +class Klass + +fun box(): String { + val kClass = Klass::class + val jClass = kClass.java + val kjClass = Klass::class.java + val kkClass = jClass.kotlin + val jjClass = kkClass.java + + assertEquals("Klass", jClass.getSimpleName()) + assertEquals("Klass", kjClass.getSimpleName()) + assertEquals("Klass", kkClass.java.simpleName) + assertEquals(kjClass, jjClass) + + try { kClass.simpleName; return "Fail 1" } catch (e: Error) {} + try { kClass.qualifiedName; return "Fail 2" } catch (e: Error) {} + try { kClass.members; return "Fail 3" } catch (e: Error) {} + + val jlError = Error::class.java + val kljError = Error::class + val jljError = kljError.java + val jlkError = jlError.kotlin + + assertEquals("Error", jlError.getSimpleName()) + assertEquals("Error", jljError.getSimpleName()) + assertEquals("Error", jlkError.java.simpleName) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/methodsFromAny/callableReferences.kt b/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/methodsFromAny/callableReferences.kt new file mode 100644 index 00000000000..b11712c344a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/methodsFromAny/callableReferences.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.reflect.KCallable +import kotlin.test.* + +class M { + fun foo() {} + val bar = 1 +} + +fun checkEquals(x: KCallable<*>, y: KCallable<*>) { + assertEquals(x, y) + assertEquals(y, x) + assertEquals(x.hashCode(), y.hashCode()) +} + +fun checkToString(x: KCallable<*>, expected: String) { + assertEquals(expected + " (Kotlin reflection is not available)", x.toString()) +} + +fun box(): String { + checkEquals(M::foo, M::foo) + checkEquals(M::bar, M::bar) + checkEquals(::M, ::M) + + checkToString(M::foo, "function foo") + checkToString(M::bar, "property bar") + checkToString(::M, "constructor") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/methodsFromAny/classReference.kt b/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/methodsFromAny/classReference.kt new file mode 100644 index 00000000000..4ed13798050 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/methodsFromAny/classReference.kt @@ -0,0 +1,27 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.reflect.KClass +import kotlin.test.* + +class M + +fun check(x: KClass<*>) { + assertEquals(x, x.java.kotlin) + assertEquals(x.hashCode(), x.java.kotlin.hashCode()) + assertEquals(x.java.toString() + " (Kotlin reflection is not available)", x.toString()) +} + +fun box(): String { + check(M::class) + check(String::class) + check(Error::class) + check(Int::class) + check(java.lang.Integer::class) + check(MutableList::class) + check(Array::class) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/primitiveJavaClass.kt b/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/primitiveJavaClass.kt new file mode 100644 index 00000000000..bf9dcabbfbb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/primitiveJavaClass.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun check(name: String, c: Class<*>) { + assertEquals(name, c.simpleName) +} + +fun box(): String { + check("boolean", Boolean::class.java) + check("byte", Byte::class.java) + check("char", Char::class.java) + check("short", Short::class.java) + check("int", Int::class.java) + check("float", Float::class.java) + check("long", Long::class.java) + check("double", Double::class.java) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/propertyGetSetName.kt b/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/propertyGetSetName.kt new file mode 100644 index 00000000000..f485e0554fe --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/propertyGetSetName.kt @@ -0,0 +1,16 @@ +// WITH_RUNTIME + +import kotlin.reflect.* + +data class Box(val value: String) + +var pr = Box("first") + +fun box(): String { + val p = ::pr + if (p.get().value != "first") return "Fail value 1: ${p.get()}" + if (p.name != "pr") return "Fail name: ${p.name}" + p.set(Box("second")) + if (p.get().value != "second") return "Fail value 2: ${p.get()}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/propertyInstanceof.kt b/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/propertyInstanceof.kt new file mode 100644 index 00000000000..bbd34af42b9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/propertyInstanceof.kt @@ -0,0 +1,37 @@ +// WITH_RUNTIME + +import kotlin.reflect.* +import kotlin.test.assertTrue +import kotlin.test.assertFalse + +class A { + val readonly: String = "" + var mutable: String = "" +} + +val readonly: String = "" +var mutable: String = "" + +fun box(): String { + assertTrue(::readonly is KProperty0<*>) + assertFalse(::readonly is KMutableProperty0<*>) + assertFalse(::readonly is KProperty1<*, *>) + assertFalse(::readonly is KProperty2<*, *, *>) + + assertTrue(::mutable is KProperty0<*>) + assertTrue(::mutable is KMutableProperty0<*>) + assertFalse(::mutable is KProperty1<*, *>) + assertFalse(::mutable is KProperty2<*, *, *>) + + assertFalse(A::readonly is KProperty0<*>) + assertTrue(A::readonly is KProperty1<*, *>) + assertFalse(A::readonly is KMutableProperty1<*, *>) + assertFalse(A::readonly is KProperty2<*, *, *>) + + assertFalse(A::mutable is KProperty0<*>) + assertTrue(A::mutable is KProperty1<*, *>) + assertTrue(A::mutable is KMutableProperty1<*, *>) + assertFalse(A::mutable is KProperty2<*, *, *>) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/reifiedTypeJavaClass.kt b/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/reifiedTypeJavaClass.kt new file mode 100644 index 00000000000..67e138a1036 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/reifiedTypeJavaClass.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +class Klass + +inline fun simpleName(): String = + T::class.java.getSimpleName() + +inline fun simpleName2(): String { + val kClass = T::class // Intrinsic for T::class.java is not used + return kClass.java.getSimpleName() +} + + +fun box(): String { + assertEquals("Integer", simpleName()) + assertEquals("Integer", simpleName2()) + assertEquals("Klass", simpleName()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/simpleClassLiterals.kt b/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/simpleClassLiterals.kt new file mode 100644 index 00000000000..406b86f608d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/noReflectAtRuntime/simpleClassLiterals.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertNotNull + +class Klass + +fun box(): String { + assertNotNull(Int::class) + assertNotNull(String::class) + assertNotNull(Klass::class) + assertNotNull(Error::class) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/parameters/boundInnerClassConstructor.kt b/backend.native/tests/external/codegen/blackbox/reflection/parameters/boundInnerClassConstructor.kt new file mode 100644 index 00000000000..03cd195f1cc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/parameters/boundInnerClassConstructor.kt @@ -0,0 +1,27 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +import kotlin.reflect.KParameter +import kotlin.test.assertEquals + +class Outer(val s1: String) { + inner class Inner(val s2: String, val s3: String = "K") { + val result = s1 + s2 + s3 + } +} + +fun KParameter.check(name: String) { + assertEquals(name, this.name!!) + assertEquals(KParameter.Kind.VALUE, this.kind) +} + +fun box(): String { + val ctor = Outer("O")::Inner + val ctorPararms = ctor.parameters + + ctorPararms[0].check("s2") + ctorPararms[1].check("s3") + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/reflection/parameters/boundObjectMemberReferences.kt b/backend.native/tests/external/codegen/blackbox/reflection/parameters/boundObjectMemberReferences.kt new file mode 100644 index 00000000000..7a98551c5da --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/parameters/boundObjectMemberReferences.kt @@ -0,0 +1,26 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.* +import kotlin.test.assertEquals + +object Host { + fun foo(i: Int, s: String) {} +} + +fun box(): String { + val fooParams = Host::foo.parameters + + assertEquals(2, fooParams.size) + + assertEquals("i", fooParams[0].name) + assertEquals(Int::class.java, fooParams[0].type.javaType) + + assertEquals("s", fooParams[1].name) + assertEquals(String::class.java, fooParams[1].type.javaType) + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/reflection/parameters/boundReferences.kt b/backend.native/tests/external/codegen/blackbox/reflection/parameters/boundReferences.kt new file mode 100644 index 00000000000..bbea4bf670b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/parameters/boundReferences.kt @@ -0,0 +1,35 @@ +// TODO: investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.* +import kotlin.test.* + +class C { + fun foo() {} + var bar = "OK" +} + +fun C.extFun(i: Int) {} + +fun KParameter.check(name: String) { + assertEquals(name, this.name!!) + assertEquals(KParameter.Kind.VALUE, this.kind) +} + +fun box(): String { + val cFoo = C()::foo + val cBar = C()::bar + val cExtFun = C()::extFun + + assertEquals(0, cFoo.parameters.size) + assertEquals(0, cBar.getter.parameters.size) + assertEquals(1, cBar.setter.parameters.size) + + assertEquals(1, cExtFun.parameters.size) + cExtFun.parameters[0].check("i") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/parameters/findParameterByName.kt b/backend.native/tests/external/codegen/blackbox/reflection/parameters/findParameterByName.kt new file mode 100644 index 00000000000..f2f150edf7a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/parameters/findParameterByName.kt @@ -0,0 +1,27 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public class J { + public void bar(int x) {} +} + +// FILE: K.kt + +import kotlin.reflect.full.findParameterByName +import kotlin.test.assertEquals +import kotlin.test.assertNull + +fun foo(x: Int) = x + +fun box(): String { + assertEquals(::foo.parameters.single(), ::foo.findParameterByName("x")) + assertNull(::foo.findParameterByName("y")) + + assertNull(J::bar.findParameterByName("x")) + assertNull(J::bar.findParameterByName("y")) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/parameters/functionParameterNameAndIndex.kt b/backend.native/tests/external/codegen/blackbox/reflection/parameters/functionParameterNameAndIndex.kt new file mode 100644 index 00000000000..3e1e388b3ee --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/parameters/functionParameterNameAndIndex.kt @@ -0,0 +1,36 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.test.assertEquals + +fun foo(bar: String): Int = bar.length + +class A(val c: String) { + fun foz(baz: Int) {} + + fun Double.mext(mez: Long) {} +} + +fun Int.qux(zux: String) {} + +fun checkParameters(f: KFunction<*>, names: List) { + val params = f.parameters + assertEquals(names, params.map { it.name }) + assertEquals(params.indices.toList(), params.map { it.index }) +} + +fun box(): String { + checkParameters(::box, listOf()) + checkParameters(::foo, listOf("bar")) + checkParameters(A::foz, listOf(null, "baz")) + checkParameters(Int::qux, listOf(null, "zux")) + + checkParameters(A::class.functions.single { it.name == "mext" }, listOf(null, null, "mez")) + + checkParameters(::A, listOf("c")) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/parameters/instanceExtensionReceiverAndValueParameters.kt b/backend.native/tests/external/codegen/blackbox/reflection/parameters/instanceExtensionReceiverAndValueParameters.kt new file mode 100644 index 00000000000..5965ee88ef4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/parameters/instanceExtensionReceiverAndValueParameters.kt @@ -0,0 +1,39 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.full.* +import kotlin.test.assertEquals +import kotlin.test.assertNotNull +import kotlin.test.assertNull + +class A { + fun String.memExt(param: Int) {} +} + +fun topLevel() {} + +fun Int.ext(vararg o: Any) {} + +fun box(): String { + A::class.members.single { it.name == "memExt" }.let { + assertNotNull(it.instanceParameter) + assertNotNull(it.extensionReceiverParameter) + assertEquals(1, it.valueParameters.size) + } + + ::topLevel.let { + assertNull(it.instanceParameter) + assertNull(it.extensionReceiverParameter) + assertEquals(0, it.valueParameters.size) + } + + Int::ext.let { + assertNull(it.instanceParameter) + assertNotNull(it.extensionReceiverParameter) + assertEquals(1, it.valueParameters.size) + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/parameters/isMarkedNullable.kt b/backend.native/tests/external/codegen/blackbox/reflection/parameters/isMarkedNullable.kt new file mode 100644 index 00000000000..710974e28b1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/parameters/isMarkedNullable.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class A { + fun foo(p1: String, p2: String?, p3: T, p4: U, p5: U?) { } +} + +fun Any?.ext() {} + +fun box(): String { + val ps = A::class.declaredFunctions.single().parameters.map { it.type.isMarkedNullable } + assertEquals(listOf(false, false, true, false, false, true), ps) + + assertTrue(Any?::ext.parameters.single().type.isMarkedNullable) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/parameters/isOptional.kt b/backend.native/tests/external/codegen/blackbox/reflection/parameters/isOptional.kt new file mode 100644 index 00000000000..d3cf38ffc2c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/parameters/isOptional.kt @@ -0,0 +1,29 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.* + +open class A { + open fun foo(x: Int, y: Int = 1) {} +} + +class B : A() { + override fun foo(x: Int, y: Int) {} +} + +class C : A() + + +fun Int.extFun() {} + +fun box(): String { + assertEquals(listOf(false, false, true), A::foo.parameters.map { it.isOptional }) + assertEquals(listOf(false, false, true), B::foo.parameters.map { it.isOptional }) + assertEquals(listOf(false, false, true), C::foo.parameters.map { it.isOptional }) + + assertFalse(Int::extFun.parameters.single().isOptional) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/parameters/javaAnnotationConstructor.kt b/backend.native/tests/external/codegen/blackbox/reflection/parameters/javaAnnotationConstructor.kt new file mode 100644 index 00000000000..99446536ed4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/parameters/javaAnnotationConstructor.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public @interface J { + short s(); + long j(); + boolean z(); + int i(); + float f(); + char c(); + double d(); +} + +// FILE: K.kt + +import kotlin.reflect.KParameter +import kotlin.test.assertEquals + +fun box(): String { + val ctor = J::class.constructors.single() + + // We sort parameters by name for consistency + assertEquals(listOf("c", "d", "f", "i", "j", "s", "z"), ctor.parameters.map { it.name }) + assert(ctor.parameters.all { it.kind == KParameter.Kind.VALUE }) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/parameters/javaParametersHaveNoNames.kt b/backend.native/tests/external/codegen/blackbox/reflection/parameters/javaParametersHaveNoNames.kt new file mode 100644 index 00000000000..0ae71fbf586 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/parameters/javaParametersHaveNoNames.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public class J { + void foo(String s, int i) {} + + static void bar(J j) {} +} + +// FILE: K.kt + +import kotlin.test.assertEquals + +fun box(): String { + assertEquals(listOf(null, null, null), J::foo.parameters.map { it.name }) + assertEquals(listOf(null), J::bar.parameters.map { it.name }) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/parameters/kinds.kt b/backend.native/tests/external/codegen/blackbox/reflection/parameters/kinds.kt new file mode 100644 index 00000000000..9e8281631ce --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/parameters/kinds.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.KParameter.Kind.* +import kotlin.test.assertEquals + +class A { + fun Int.foo(x: String) {} + + inner class Inner(s: String) {} +} + +fun box(): String { + val foo = A::class.memberExtensionFunctions.single() + + assertEquals(listOf(INSTANCE, EXTENSION_RECEIVER, VALUE), foo.parameters.map { it.kind }) + assertEquals(listOf(INSTANCE, VALUE), A::Inner.parameters.map { it.kind }) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/parameters/propertySetter.kt b/backend.native/tests/external/codegen/blackbox/reflection/parameters/propertySetter.kt new file mode 100644 index 00000000000..9b50df6eb51 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/parameters/propertySetter.kt @@ -0,0 +1,29 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.test.assertEquals + +var default: Int = 0 + +var defaultAnnotated: Int = 0 + public set + +var custom: Int = 0 + set(myName: Int) {} + +fun checkPropertySetterParam(property: KMutableProperty<*>, name: String?) { + val parameter = property.setter.parameters.single() + assertEquals(0, parameter.index) + assertEquals(name, parameter.name) +} + +fun box(): String { + checkPropertySetterParam(::default, null) + checkPropertySetterParam(::defaultAnnotated, null) + checkPropertySetterParam(::custom, "myName") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/accessors/accessorNames.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/accessors/accessorNames.kt new file mode 100644 index 00000000000..9750f307a4f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/accessors/accessorNames.kt @@ -0,0 +1,35 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.test.assertEquals + +var foo = "" +var String.bar: String + get() = this + set(value) {} + +class A(var baz: Int) { + var String.quux: String + get() = this + set(value) {} +} + +fun box(): String { + assertEquals("", ::foo.getter.name) + assertEquals("", ::foo.setter.name) + + assertEquals("", String::bar.getter.name) + assertEquals("", String::bar.setter.name) + + assertEquals("", A::baz.getter.name) + assertEquals("", A::baz.setter.name) + + val me = A::class.memberExtensionProperties.single() as KMutableProperty2 + assertEquals("", me.getter.name) + assertEquals("", me.setter.name) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/accessors/extensionPropertyAccessors.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/accessors/extensionPropertyAccessors.kt new file mode 100644 index 00000000000..db64040fe10 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/accessors/extensionPropertyAccessors.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +var state: String = "" + +var String.prop: String + get() = length.toString() + set(value) { state = this + value } + +fun box(): String { + val prop = String::prop + + assertEquals("3", prop.getter.invoke("abc")) + assertEquals("5", prop.getter("defgh")) + + prop.setter("O", "K") + + return state +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/accessors/memberExtensions.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/accessors/memberExtensions.kt new file mode 100644 index 00000000000..afcf1c0eb57 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/accessors/memberExtensions.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.test.assertEquals + +class C(var state: String) { + var String.prop: String + get() = length.toString() + set(value) { state = this + value } +} + +fun box(): String { + val prop = C::class.memberExtensionProperties.single() as KMutableProperty2 + + val c = C("") + assertEquals("3", prop.getter.invoke(c, "abc")) + assertEquals("1", prop.getter(c, "d")) + + prop.setter(c, "O", "K") + + return c.state +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/accessors/memberPropertyAccessors.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/accessors/memberPropertyAccessors.kt new file mode 100644 index 00000000000..9a3d6d97b39 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/accessors/memberPropertyAccessors.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +class C(var state: String) + +fun box(): String { + val prop = C::state + + val c = C("1") + assertEquals("1", prop.getter.invoke(c)) + assertEquals("1", prop.getter(c)) + + prop.setter(c, "OK") + + return prop.get(c) +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/accessors/topLevelPropertyAccessors.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/accessors/topLevelPropertyAccessors.kt new file mode 100644 index 00000000000..c896fe0882c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/accessors/topLevelPropertyAccessors.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +var state: String = "" + +fun box(): String { + val prop = ::state + + assertEquals("", prop.getter.invoke()) + assertEquals("", prop.getter()) + + prop.setter("OK") + + return prop.get() +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/allVsDeclared.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/allVsDeclared.kt new file mode 100644 index 00000000000..58970f582d8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/allVsDeclared.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.test.* + +open class Super { + val a: Int = 1 + val String.b: String get() = this +} + +class Sub : Super() { + val c: Double = 1.0 + val Char.d: Char get() = this +} + +fun box(): String { + val sub = Sub::class + + assertEquals(listOf("a", "c"), sub.memberProperties.map { it.name }.sorted()) + assertEquals(listOf("b", "d"), sub.memberExtensionProperties.map { it.name }.sorted()) + assertEquals(listOf("c"), sub.declaredMemberProperties.map { it.name }) + assertEquals(listOf("d"), sub.declaredMemberExtensionProperties.map { it.name }) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/callPrivatePropertyFromGetProperties.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/callPrivatePropertyFromGetProperties.kt new file mode 100644 index 00000000000..0006b5c4efe --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/callPrivatePropertyFromGetProperties.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.* + +class K(private val value: String) + +fun box(): String { + val p = K::class.java.kotlin.memberProperties.single() as KProperty1 + + try { + return p.get(K("Fail: private property should not be accessible by default")) + } + catch (e: IllegalCallableAccessException) { + // OK + } + + p.isAccessible = true + + return p.get(K("OK")) +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/declaredVsInheritedProperties.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/declaredVsInheritedProperties.kt new file mode 100644 index 00000000000..53e5eaf3aca --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/declaredVsInheritedProperties.kt @@ -0,0 +1,70 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public class J { + public String publicMemberJ; + private String privateMemberJ; + public static String publicStaticJ; + private static String privateStaticJ; +} + +// FILE: K.kt + +import kotlin.reflect.* +import kotlin.test.assertEquals + +open class K : J() { + public val publicMemberK: String = "" + private val privateMemberK: String = "" + public val Any.publicMemberExtensionK: String get() = "" + private val Any.privateMemberExtensionK: String get() = "" +} + +class L : K() + +fun Collection>.names(): Set = + this.map { it.name }.toSet() + +fun check(c: Collection>, names: Set) { + assertEquals(names, c.names()) +} + +fun box(): String { + val j = J::class + + check(j.staticProperties, + setOf("publicStaticJ", "privateStaticJ")) + check(j.declaredMemberProperties, + setOf("publicMemberJ", "privateMemberJ")) + check(j.declaredMemberExtensionProperties, + emptySet()) + + check(j.memberProperties, j.declaredMemberProperties.names()) + check(j.memberExtensionProperties, emptySet()) + + val k = K::class + + check(k.staticProperties, + emptySet()) + check(k.declaredMemberProperties, + setOf("publicMemberK", "privateMemberK")) + check(k.declaredMemberExtensionProperties, + setOf("publicMemberExtensionK", "privateMemberExtensionK")) + + check(k.memberProperties, setOf("publicMemberJ") + k.declaredMemberProperties.names()) + check(k.memberExtensionProperties, k.declaredMemberExtensionProperties.names()) + + + val l = L::class + + check(l.staticProperties, emptySet()) + check(l.declaredMemberProperties, emptySet()) + check(l.declaredMemberExtensionProperties, emptySet()) + check(l.memberProperties, setOf("publicMemberJ", "publicMemberK")) + check(l.memberExtensionProperties, setOf("publicMemberExtensionK")) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/fakeOverridesInSubclass.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/fakeOverridesInSubclass.kt new file mode 100644 index 00000000000..abeae583ff4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/fakeOverridesInSubclass.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.test.* + +open class Super(val r: String) + +class Sub(r: String) : Super(r) + +fun box(): String { + val props = Sub::class.java.kotlin.declaredMemberProperties + if (!props.isEmpty()) return "Fail $props" + + val allProps = Sub::class.java.kotlin.memberProperties + assertEquals(listOf("r"), allProps.map { it.name }) + return allProps.single().get(Sub("OK")) as String +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/genericClassLiteralPropertyReceiverIsStar.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/genericClassLiteralPropertyReceiverIsStar.kt new file mode 100644 index 00000000000..c662235809e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/genericClassLiteralPropertyReceiverIsStar.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* + +class A { + val result = "OK" +} + +fun box(): String { + val k: KProperty1, *> = A::class.memberProperties.single() + return k.get(A()) as String +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/genericOverriddenProperty.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/genericOverriddenProperty.kt new file mode 100644 index 00000000000..5f31f518c65 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/genericOverriddenProperty.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// KT-13700 Exception obtaining descriptor for property reference + +import kotlin.test.assertEquals + +interface H { + val parent : T? +} + +interface A : H + +fun box(): String { + assertEquals("A?", A::parent.returnType.toString()) + assertEquals("T?", H::parent.returnType.toString()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/genericProperty.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/genericProperty.kt new file mode 100644 index 00000000000..e50b948af6f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/genericProperty.kt @@ -0,0 +1,14 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +data class Box(val element: T) + +fun box(): String { + val p = Box::element + assertEquals("val Box.element: T", p.toString()) + return p.call(Box("OK")) +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/getExtensionPropertiesMutableVsReadonly.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/getExtensionPropertiesMutableVsReadonly.kt new file mode 100644 index 00000000000..13b0c3fbec9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/getExtensionPropertiesMutableVsReadonly.kt @@ -0,0 +1,31 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* + +var storage = "before" + +class A { + val String.readonly: String + get() = this + + var String.mutable: String + get() = storage + set(value) { storage = value } +} + +fun box(): String { + val props = A::class.java.kotlin.memberExtensionProperties + val readonly = props.single { it.name == "readonly" } + assert(readonly !is KMutableProperty2) { "Fail 1: $readonly" } + val mutable = props.single { it.name == "mutable" } + assert(mutable is KMutableProperty2) { "Fail 2: $mutable" } + + val a = A() + mutable as KMutableProperty2 + assert(mutable.get(a, "") == "before") { "Fail 3: ${mutable.get(a, "")}" } + mutable.set(a, "", "OK") + return mutable.get(a, "") +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/getPropertiesMutableVsReadonly.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/getPropertiesMutableVsReadonly.kt new file mode 100644 index 00000000000..736d0a33b91 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/getPropertiesMutableVsReadonly.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* + +class A(val readonly: String) { + var mutable: String = "before" +} + +fun box(): String { + val props = A::class.java.kotlin.memberProperties + val readonly = props.single { it.name == "readonly" } + assert(readonly !is KMutableProperty1) { "Fail 1: $readonly" } + val mutable = props.single { it.name == "mutable" } + assert(mutable is KMutableProperty1) { "Fail 2: $mutable" } + + val a = A("") + mutable as KMutableProperty1 + assert(mutable.get(a) == "before") { "Fail 3: ${mutable.get(a)}" } + mutable.set(a, "OK") + return mutable.get(a) +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/invokeKProperty.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/invokeKProperty.kt new file mode 100644 index 00000000000..4b1709d8116 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/invokeKProperty.kt @@ -0,0 +1,12 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.declaredMemberProperties + +class A(val foo: String) + +fun box(): String { + return (A::class.declaredMemberProperties.single()).invoke(A("OK")) as String +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/javaPropertyInheritedInKotlin.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/javaPropertyInheritedInKotlin.kt new file mode 100644 index 00000000000..2c246b57836 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/javaPropertyInheritedInKotlin.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: J.java + +public class J { + public String result = null; +} + +// FILE: K.kt + +class K : J() + +fun box(): String { + val k = K() + val p = K::result + if (p.get(k) != null) return "Fail" + p.set(k, "OK") + return p.get(k) +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/javaStaticField.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/javaStaticField.kt new file mode 100644 index 00000000000..77e92fbb187 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/javaStaticField.kt @@ -0,0 +1,36 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public class J { + public static String x; + + static String packageLocalField; +} + +// FILE: K.kt + +import kotlin.test.assertEquals + +fun box(): String { + val f = J::x + assertEquals("x", f.name) + + assertEquals(f, J::class.members.single { it.name == "x" }) + + f.set("OK") + assertEquals("OK", J.x) + assertEquals("OK", f.getter()) + + val pl = J::packageLocalField.getter + try { + pl() + return "Fail: package local field must be inaccessible" + } catch (e: Exception) { + // OK + } + + return f.get() +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/kotlinPropertyInheritedInJava.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/kotlinPropertyInheritedInJava.kt new file mode 100644 index 00000000000..20166493f5a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/kotlinPropertyInheritedInJava.kt @@ -0,0 +1,52 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public class J extends K { +} + +// FILE: K.kt + +import kotlin.reflect.* +import kotlin.reflect.jvm.* + +public open class K { + var prop: String = ":(" + + val Int.ext: Int get() = this +} + +fun box(): String { + val j = J() + + val prop = J::prop + if (prop !is KMutableProperty1<*, *>) return "Fail instanceof" + if (prop.name != "prop") return "Fail name: ${prop.name}" + if (prop.get(j) != ":(") return "Fail get before: ${prop.get(j)}" + prop.set(j, ":)") + if (prop.get(j) != ":)") return "Fail get after: ${prop.get(j)}" + + + if (prop == K::prop) return "Fail J::prop == K::prop (these are different properties)" + + + val klass = J::class.java.kotlin + if (klass.declaredMemberProperties.isNotEmpty()) return "Fail: declaredMemberProperties should be empty" + if (klass.declaredMemberExtensionProperties.isNotEmpty()) return "Fail: declaredMemberExtensionProperties should be empty" + + val prop2 = klass.memberProperties.firstOrNull { it.name == "prop" } ?: "Fail: no 'prop' property in memberProperties" + if (prop != prop2) return "Fail: property references from :: and from properties differ: $prop != $prop2" + if (prop2 !is KMutableProperty1<*, *>) return "Fail instanceof 2" + (prop2 as KMutableProperty1).set(j, "::)") + if (prop.get(j) != "::)") return "Fail get after 2: ${prop.get(j)}" + + + val ext = klass.memberExtensionProperties.firstOrNull { it.name == "ext" } ?: "Fail: no 'ext' property in memberExtensionProperties" + ext as KProperty2 + val fortyTwo = ext.get(j, 42) + if (fortyTwo != 42) return "Fail ext get: $fortyTwo" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/memberAndMemberExtensionWithSameName.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/memberAndMemberExtensionWithSameName.kt new file mode 100644 index 00000000000..1078c0380f9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/memberAndMemberExtensionWithSameName.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* + +class A { + val foo: String = "member" + val Unit.foo: String get() = "extension" +} + +fun box(): String { + run { + val foo: KProperty1 = A::class.java.kotlin.memberProperties.single() + assert(foo.name == "foo") { "Fail name: $foo (${foo.name})" } + assert(foo.get(A()) == "member") { "Fail value: ${foo.get(A())}" } + } + + run { + val foo: KProperty2 = A::class.java.kotlin.memberExtensionProperties.single() + assert(foo.name == "foo") { "Fail name: $foo (${foo.name})" } + foo as KProperty2 + assert(foo.get(A(), Unit) == "extension") { "Fail value: ${foo.get(A(), Unit)}" } + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/mutatePrivateJavaInstanceField.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/mutatePrivateJavaInstanceField.kt new file mode 100644 index 00000000000..9522b302d13 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/mutatePrivateJavaInstanceField.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public class J { + private String result = "Fail"; +} + +// FILE: K.kt + +import kotlin.reflect.* +import kotlin.reflect.jvm.* + +fun box(): String { + val a = J() + val p = J::class.members.single { it.name == "result" } as KMutableProperty1 + p.isAccessible = true + p.set(a, "OK") + return p.get(a) +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/mutatePrivateJavaStaticField.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/mutatePrivateJavaStaticField.kt new file mode 100644 index 00000000000..541df83fb82 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/mutatePrivateJavaStaticField.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public class J { + private static String result = "Fail"; +} + +// FILE: K.kt + +import kotlin.reflect.* +import kotlin.reflect.jvm.* + +fun box(): String { + val a = J() + val p = J::class.members.single { it.name == "result" } as KMutableProperty0 + p.isAccessible = true + p.set("OK") + return p.get() +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/noConflictOnKotlinGetterAndJavaField.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/noConflictOnKotlinGetterAndJavaField.kt new file mode 100644 index 00000000000..09a15935bc9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/noConflictOnKotlinGetterAndJavaField.kt @@ -0,0 +1,35 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public class J { + public String foo = ""; +} + +// FILE: K.kt + +import kotlin.test.* + +class K : J() { + fun getFoo(): String = "K" +} + +fun box(): String { + val j = J() + val x = J::foo + x.set(j, "J") + assertEquals("J", x.get(j)) + + val k = K() + val y = K::foo + y.set(k, "K") + assertEquals("K", y.get(k)) + assertEquals("K", x.get(k)) + + val z = K::getFoo + assertEquals("K", z.invoke(k)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/overrideKotlinPropertyByJavaMethod.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/overrideKotlinPropertyByJavaMethod.kt new file mode 100644 index 00000000000..ea3b816568d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/overrideKotlinPropertyByJavaMethod.kt @@ -0,0 +1,42 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public class J implements K { + private String foo; + + @Override + public String getFoo() { + return foo; + } + + @Override + public void setFoo(String s) { + foo = s; + } +} + +// FILE: K.kt + +import kotlin.test.assertEquals +import kotlin.reflect.KParameter + +interface K { + var foo: String +} + +fun box(): String { + val p = J::foo + assertEquals("foo", p.name) + + if (p.parameters.size != 1) return "Should have only 1 parameter" + if (p.parameters.single().kind != KParameter.Kind.INSTANCE) return "Should have an instance parameter" + + if (J::class.members.none { it == p }) return "No foo in members" + + val j = J() + p.setter.call(j, "OK") + return p.getter.call(j) +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/privateClassVal.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/privateClassVal.kt new file mode 100644 index 00000000000..6e4e20f4f72 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/privateClassVal.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.isAccessible + +class Result { + private val value = "OK" + + fun ref() = Result::class.memberProperties.single() as KProperty1 +} + +fun box(): String { + val p = Result().ref() + try { + p.get(Result()) + return "Fail: private property is accessible by default" + } catch(e: IllegalCallableAccessException) { } + + p.isAccessible = true + + val r = p.get(Result()) + + p.isAccessible = false + try { + p.get(Result()) + return "Fail: setAccessible(false) had no effect" + } catch(e: IllegalCallableAccessException) { } + + return r +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/privateClassVar.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/privateClassVar.kt new file mode 100644 index 00000000000..be1cf290bcd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/privateClassVar.kt @@ -0,0 +1,35 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.isAccessible + +class A { + private var value = 0 + + fun ref() = A::class.memberProperties.single() as KMutableProperty1 +} + +fun box(): String { + val a = A() + val p = a.ref() + try { + p.set(a, 1) + return "Fail: private property is accessible by default" + } catch(e: IllegalCallableAccessException) { } + + p.isAccessible = true + + p.set(a, 2) + p.get(a) + + p.isAccessible = false + try { + p.set(a, 3) + return "Fail: setAccessible(false) had no effect" + } catch(e: IllegalCallableAccessException) { } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/privateFakeOverrideFromSuperclass.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/privateFakeOverrideFromSuperclass.kt new file mode 100644 index 00000000000..0ac136eed17 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/privateFakeOverrideFromSuperclass.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* + +open class A(private val p: Int) +class B : A(42) + +fun box() = + if (B::class.memberProperties.isEmpty()) "OK" + else "Fail: invisible fake overrides should not appear in KClass.memberProperties" diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/privateJvmStaticVarInObject.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/privateJvmStaticVarInObject.kt new file mode 100644 index 00000000000..9aabee699a0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/privateJvmStaticVarInObject.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.* + +object Obj { + @JvmStatic + private var result: String = "Fail" +} + +fun box(): String { + val p = Obj::class.members.single { it.name == "result" } as KMutableProperty1 + p.isAccessible = true + + try { + p.set(null, "OK") + return "Fail: set should check that first argument is Obj" + } catch (e: IllegalArgumentException) {} + + try { + p.get(null) + return "Fail: get should check that first argument is Obj" + } catch (e: IllegalArgumentException) {} + + p.set(Obj, "OK") + return p.get(Obj) +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/privatePropertyCallIsAccessibleOnAccessors.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/privatePropertyCallIsAccessibleOnAccessors.kt new file mode 100644 index 00000000000..d15f8b9e09f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/privatePropertyCallIsAccessibleOnAccessors.kt @@ -0,0 +1,46 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.* +import kotlin.test.* + +class A(private var foo: String) + +fun box(): String { + val a = A("") + val foo = A::class.memberProperties.single() as KMutableProperty1 + + assertTrue(!foo.isAccessible) + assertTrue(!foo.getter.isAccessible) + assertTrue(!foo.setter.isAccessible) + + val setter = foo.setter + setter.isAccessible = true + assertTrue(setter.isAccessible) + assertTrue(foo.setter.isAccessible) + + // After we invoked isAccessible on a setter, the underlying field and thus the getter are also accessible + assertTrue(foo.isAccessible) + assertTrue(foo.getter.isAccessible) + setter.call(a, "A") + assertEquals("A", foo.getter.call(a)) + + setter.isAccessible = false + assertFalse(setter.isAccessible) + assertFalse(foo.setter.isAccessible) + assertFalse(foo.getter.isAccessible) + assertFalse(foo.isAccessible) + + val getter = foo.getter + getter.isAccessible = true + assertTrue(setter.isAccessible) + assertTrue(foo.setter.isAccessible) + assertTrue(foo.isAccessible) + assertTrue(foo.getter.isAccessible) + assertTrue(getter.isAccessible) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/privateToThisAccessors.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/privateToThisAccessors.kt new file mode 100644 index 00000000000..0abecc51601 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/privateToThisAccessors.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.* + +class K { + private var t: T + get() = "OK" as T + set(value) {} + + fun run(): String { + val p = K::class.memberProperties.single() as KMutableProperty1, String> + p.isAccessible = true + p.set(this as K, "") + return p.get(this) as String + } +} + +fun box() = K().run() diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/propertyOfNestedClassAndArrayType.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/propertyOfNestedClassAndArrayType.kt new file mode 100644 index 00000000000..cca3ef60307 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/propertyOfNestedClassAndArrayType.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KMutableProperty1 + +class A { + class B(val result: String) + + var p: A.B? = null + var q: Array>? = null +} + +fun box(): String { + val a = A() + + val aq = A::class.members.single { it.name == "q" } as KMutableProperty1>> + aq.set(a, arrayOf(arrayOf(A.B("array")))) + if (a.q!![0][0].result != "array") return "Fail array" + + val ap = A::class.members.single { it.name == "p" } as KMutableProperty1 + ap.set(a, A.B("OK")) + return a.p!!.result +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/protectedClassVar.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/protectedClassVar.kt new file mode 100644 index 00000000000..7c915af12df --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/protectedClassVar.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.jvm.isAccessible + +class A(param: String) { + protected var v: String = param + + fun ref() = A::class.memberProperties.single() as KMutableProperty1 +} + +fun box(): String { + val a = A(":(") + val f = a.ref() + + try { + f.get(a) + return "Fail: protected property getter is accessible by default" + } catch (e: IllegalCallableAccessException) { } + + try { + f.set(a, ":D") + return "Fail: protected property setter is accessible by default" + } catch (e: IllegalCallableAccessException) { } + + f.isAccessible = true + + f.set(a, ":)") + + return if (f.get(a) != ":)") "Fail: ${f.get(a)}" else "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/publicClassValAccessible.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/publicClassValAccessible.kt new file mode 100644 index 00000000000..1e2837c17ef --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/publicClassValAccessible.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.isAccessible + +class Result { + public val value: String = "OK" +} + +fun box(): String { + val p = Result::value + p.isAccessible = false + // setAccessible(false) should have no effect on the accessibility of a public reflection object + return p.get(Result()) +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/referenceToJavaFieldOfKotlinSubclass.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/referenceToJavaFieldOfKotlinSubclass.kt new file mode 100644 index 00000000000..f634dab9d71 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/referenceToJavaFieldOfKotlinSubclass.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: J.java + +public class J extends K { + public final int value = 42; +} + +// FILE: K.kt + +open class K + +fun box(): String { + val f = J::value + val a = J() + return if (f.get(a) == 42) "OK" else "Fail: ${f.get(a)}" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/properties/simpleGetProperties.kt b/backend.native/tests/external/codegen/blackbox/reflection/properties/simpleGetProperties.kt new file mode 100644 index 00000000000..f14387359b6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/properties/simpleGetProperties.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.* + +class A(param: String) { + val int: Int get() = 42 + val string: String = param + var anyVar: Any? = null + + val List.extensionToList: Unit get() {} + + fun notAProperty() {} +} + +fun box(): String { + val klass = A::class.java.kotlin + + val props = klass.memberProperties + + val names = props.map { it.name }.sorted() + assert(names == listOf("anyVar", "int", "string")) { "Fail names: $props" } + + val stringProp = props.firstOrNull { it.name == "string" } ?: return "Fail, string not found: $props" + return stringProp.get(A("OK")) as String +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/specialBuiltIns/getMembersOfStandardJavaClasses.kt b/backend.native/tests/external/codegen/blackbox/reflection/specialBuiltIns/getMembersOfStandardJavaClasses.kt new file mode 100644 index 00000000000..d1ae9ba0f8d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/specialBuiltIns/getMembersOfStandardJavaClasses.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FULL_JDK +// See KT-11258 Incorrect resolution sequence for Java field + +import java.util.* + +fun box(): String { + listOf( + ArrayList::class, + LinkedList::class, + AbstractList::class, + HashSet::class, + TreeSet::class, + HashMap::class, + TreeMap::class, + AbstractMap::class, + AbstractMap.SimpleEntry::class + ).map { + it.members.map(Any::toString) + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/supertypes/builtInClassSupertypes.kt b/backend.native/tests/external/codegen/blackbox/reflection/supertypes/builtInClassSupertypes.kt new file mode 100644 index 00000000000..0fe836de76b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/supertypes/builtInClassSupertypes.kt @@ -0,0 +1,47 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import java.io.Serializable +import kotlin.reflect.KClass +import kotlin.reflect.KCallable +import kotlin.reflect.full.* +import kotlin.test.assertEquals + +inline fun check(vararg callables: KCallable<*>) { + val types = callables.map { it.returnType } + assertEquals(types, T::class.supertypes) + assertEquals(types.map { it.classifier as KClass<*> }, T::class.superclasses) +} + +inline fun checkAll(vararg callables: KCallable<*>) { + val types = callables.map { it.returnType } + // Calling toSet because the order of returned types/classes is not specified + assertEquals(types.toSet(), T::class.allSupertypes.toSet()) + assertEquals(types.map { it.classifier as KClass<*> }.toSet(), T::class.allSuperclasses.toSet()) +} + +fun comparableOfString(): Comparable = null!! +fun charSequence(): CharSequence = null!! +fun serializable(): Serializable = null!! +fun any(): Any = null!! +fun number(): Number = null!! +fun comparableOfInt(): Comparable = null!! +fun cloneable(): Cloneable = null!! + +fun box(): String { + check() + checkAll() + + check(::comparableOfString, ::charSequence, ::serializable) + checkAll(::comparableOfString, ::charSequence, ::serializable, ::any) + + check(::number, ::comparableOfInt, ::serializable) + checkAll(::number, ::comparableOfInt, ::serializable, ::any) + + check>(::any, ::cloneable, ::serializable) + checkAll>(::any, ::cloneable, ::serializable) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/supertypes/genericSubstitution.kt b/backend.native/tests/external/codegen/blackbox/reflection/supertypes/genericSubstitution.kt new file mode 100644 index 00000000000..618ac48b2f3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/supertypes/genericSubstitution.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.full.allSupertypes +import kotlin.test.assertEquals + +interface A +interface B : A +interface C : B +interface D : C + +interface StringList : List + +fun box(): String { + assertEquals( + listOf(String::class, Int::class), + D::class.allSupertypes.single { it.classifier == A::class }.arguments.map { it.type!!.classifier } + ) + + val collectionType = StringList::class.allSupertypes.single { it.classifier == Collection::class } + val arg = collectionType.arguments.single().type!! + // TODO: this does not work currently because for some reason two different instances of TypeParameterDescriptor are created for List + // assertEquals(String::class, arg.classifier) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/supertypes/isSubclassOfIsSuperclassOf.kt b/backend.native/tests/external/codegen/blackbox/reflection/supertypes/isSubclassOfIsSuperclassOf.kt new file mode 100644 index 00000000000..efbc87e30e5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/supertypes/isSubclassOfIsSuperclassOf.kt @@ -0,0 +1,52 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KClass +import kotlin.reflect.full.* +import kotlin.test.assertTrue +import kotlin.test.assertFalse + +open class Klass +interface Interface +class Bar : Interface, Klass() + +fun check(subclass: KClass<*>, superclass: KClass<*>, shouldBeSubclass: Boolean) { + if (shouldBeSubclass) { + assertTrue(subclass.isSubclassOf(superclass)) + assertTrue(superclass.isSuperclassOf(subclass)) + } else { + assertFalse(subclass.isSubclassOf(superclass)) + assertFalse(superclass.isSuperclassOf(subclass)) + } +} + +fun box(): String { + check(Any::class, Any::class, true) + check(String::class, Any::class, true) + check(Any::class, String::class, false) + check(String::class, String::class, true) + + check(Int::class, Int::class, true) + check(Int::class, Any::class, true) + + check(List::class, Collection::class, true) + check(List::class, Iterable::class, true) + check(Collection::class, Iterable::class, true) + check(Set::class, List::class, false) + + check(Array::class, Array::class, false) + check(Array::class, Array::class, false) + + check(Function3::class, Function4::class, false) + check(Function4::class, Function3::class, false) + + check(Bar::class, Klass::class, true) + check(Bar::class, Interface::class, true) + check(Klass::class, Bar::class, false) + check(Interface::class, Bar::class, false) + check(Klass::class, Interface::class, false) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/supertypes/primitives.kt b/backend.native/tests/external/codegen/blackbox/reflection/supertypes/primitives.kt new file mode 100644 index 00000000000..9cf5410c504 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/supertypes/primitives.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.full.isSubclassOf +import kotlin.test.assertTrue +import kotlin.test.assertFalse + +fun box(): String { + // KClass instances for primitive int and wrapper java.lang.Integer are different + val primitiveInt = Int::class.javaPrimitiveType!!.kotlin + val wrapperInt = Int::class.javaObjectType.kotlin + assertTrue(primitiveInt.isSubclassOf(primitiveInt)) + assertTrue(wrapperInt.isSubclassOf(wrapperInt)) + + // KClass for int equals KClass for java.lang.Integer, so they are also a subclass of each other + assertTrue(primitiveInt.isSubclassOf(wrapperInt)) + assertTrue(wrapperInt.isSubclassOf(primitiveInt)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/supertypes/simpleSupertypes.kt b/backend.native/tests/external/codegen/blackbox/reflection/supertypes/simpleSupertypes.kt new file mode 100644 index 00000000000..c17e7ce9529 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/supertypes/simpleSupertypes.kt @@ -0,0 +1,52 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.full.* +import kotlin.test.assertEquals + +open class Simple +class OneClass : Simple() + +interface Interface +interface Interface2 +class ClassAndTwoInterfaces : Interface, Simple(), Interface2 + +fun any(): Any = null!! +fun simple(): Simple = null!! +fun interface_(): Interface = null!! +fun interface2(): Interface2 = null!! + +fun box(): String { + with(Simple::class) { + assertEquals(listOf(::any.returnType), supertypes) + assertEquals(listOf(Any::class), superclasses) + // Calling toSet because the order of returned types/classes is not specified + assertEquals(setOf(::any.returnType), allSupertypes.toSet()) + assertEquals(setOf(Any::class), allSuperclasses.toSet()) + } + + with (OneClass::class) { + assertEquals(listOf(::simple.returnType), supertypes) + assertEquals(listOf(Simple::class), superclasses) + assertEquals(setOf(::simple.returnType, ::any.returnType), allSupertypes.toSet()) + assertEquals(setOf(Simple::class, Any::class), allSuperclasses.toSet()) + } + + with (Interface::class) { + assertEquals(listOf(::any.returnType), supertypes) + assertEquals(listOf(Any::class), superclasses) + assertEquals(setOf(::any.returnType), allSupertypes.toSet()) + assertEquals(setOf(Any::class), allSuperclasses.toSet()) + } + + with (ClassAndTwoInterfaces::class) { + assertEquals(listOf(::interface_.returnType, ::simple.returnType, ::interface2.returnType), supertypes) + assertEquals(listOf(Interface::class, Simple::class, Interface2::class), superclasses) + assertEquals(setOf(::interface_.returnType, ::simple.returnType, ::interface2.returnType, ::any.returnType), allSupertypes.toSet()) + assertEquals(setOf(Interface::class, Simple::class, Interface2::class, Any::class), allSuperclasses.toSet()) + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/typeParameters/declarationSiteVariance.kt b/backend.native/tests/external/codegen/blackbox/reflection/typeParameters/declarationSiteVariance.kt new file mode 100644 index 00000000000..51262ffdbad --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/typeParameters/declarationSiteVariance.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KVariance +import kotlin.test.assertEquals + +class Triple { + fun foo(): T = null!! +} + +fun box(): String { + assertEquals( + listOf( + KVariance.IN, + KVariance.INVARIANT, + KVariance.OUT + ), + Triple::class.typeParameters.map { it.variance } + ) + + assertEquals(KVariance.INVARIANT, Triple::class.members.single { it.name == "foo" }.typeParameters.single().variance) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/typeParameters/typeParametersAndNames.kt b/backend.native/tests/external/codegen/blackbox/reflection/typeParameters/typeParametersAndNames.kt new file mode 100644 index 00000000000..2ad93a4d12a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/typeParameters/typeParametersAndNames.kt @@ -0,0 +1,39 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KClass +import kotlin.test.assertEquals + +class F { + fun foo() {} + val B.bar: B get() = this +} + +class C { + fun baz() {} + fun quux() {} +} + +fun get(klass: KClass<*>, memberName: String? = null): List = + (if (memberName != null) + klass.members.single { it.name == memberName }.typeParameters + else + klass.typeParameters) + .map { it.name } + +fun box(): String { + assertEquals(listOf(), get(F::class)) + assertEquals(listOf("A"), get(F::class, "foo")) + assertEquals(listOf("B"), get(F::class, "bar")) + + assertEquals(listOf("D"), get(C::class)) + assertEquals(listOf(), get(C::class, "baz")) + assertEquals(listOf("E", "G"), get(C::class, "quux")) + + assertEquals(listOf("T"), get(Comparable::class)) + assertEquals(listOf(), get(String::class)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/typeParameters/upperBounds.kt b/backend.native/tests/external/codegen/blackbox/reflection/typeParameters/upperBounds.kt new file mode 100644 index 00000000000..37f2c4ae2a4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/typeParameters/upperBounds.kt @@ -0,0 +1,62 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KTypeProjection +import kotlin.reflect.KVariance +import kotlin.test.assertEquals + +class DefaultBound +class NullableAnyBound +class NotNullAnyBound +class TwoBounds where T : Comparable + +class OtherParameterBound + +class RecursiveGeneric> + +class FunctionTypeParameter { + fun foo(): Cloneable = null!! +} + +// helper functions to obtain KType instances +fun nullableAny(): Any? = null +fun notNullAny(): Any = null!! + +fun box(): String { + assertEquals(listOf(::nullableAny.returnType), DefaultBound::class.typeParameters.single().upperBounds) + assertEquals(listOf(::nullableAny.returnType), NullableAnyBound::class.typeParameters.single().upperBounds) + assertEquals(listOf(::notNullAny.returnType), NotNullAnyBound::class.typeParameters.single().upperBounds) + + TwoBounds::class.typeParameters.single().let { + val (cl, cm) = it.upperBounds + assertEquals(Cloneable::class, cl.classifier) + assertEquals(listOf(), cl.arguments) + + assertEquals(Comparable::class, cm.classifier) + val cmt = cm.arguments.single() + assertEquals(KVariance.INVARIANT, cmt.variance) + assertEquals(it, cmt.type!!.classifier) + } + + OtherParameterBound::class.typeParameters.let { + val (t, u) = it + assertEquals(u, t.upperBounds.single().classifier) + assertEquals(Number::class, u.upperBounds.single().classifier) + } + + FunctionTypeParameter::class.members.single { it.name == "foo" }.let { foo -> + assertEquals(foo.returnType, foo.typeParameters.single().upperBounds.single()) + } + + val recursiveGenericTypeParameter = RecursiveGeneric::class.typeParameters.single() + val recursiveGenericBound = recursiveGenericTypeParameter.upperBounds.single() + assertEquals(Enum::class, recursiveGenericBound.classifier) + recursiveGenericBound.arguments.single().let { projection -> + assertEquals(KVariance.INVARIANT, projection.variance) + assertEquals(recursiveGenericTypeParameter, projection.type!!.classifier) + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/classifierIsClass.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/classifierIsClass.kt new file mode 100644 index 00000000000..13f0031e6aa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/classifierIsClass.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.assertEquals + +class Outer { + class Nested + + inner class Inner +} + +fun outer(): Outer = null!! +fun nested(): Outer.Nested = null!! +fun inner(): Outer.Inner = null!! + +fun array(): Array = null!! + +fun box(): String { + assertEquals(Outer::class, ::outer.returnType.classifier) + assertEquals(Outer.Nested::class, ::nested.returnType.classifier) + assertEquals(Outer.Inner::class, ::inner.returnType.classifier) + + assertEquals(Array::class, ::array.returnType.classifier) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/classifierIsTypeParameter.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/classifierIsTypeParameter.kt new file mode 100644 index 00000000000..03f3fc828e1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/classifierIsTypeParameter.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KTypeParameter +import kotlin.test.* + +class A { + fun foo(): T = null!! + fun bar(): Array? = null!! +} + +fun box(): String { + val t = A::class.members.single { it.name == "foo" }.returnType + assertFalse(t.isMarkedNullable) + val tc = t.classifier + if (tc !is KTypeParameter) fail(tc.toString()) + assertEquals("T", tc.name) + + val u = A::class.members.single { it.name == "bar" }.returnType + assertTrue(u.isMarkedNullable) + assertEquals(Array::class, u.classifier) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/classifiersOfBuiltInTypes.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/classifiersOfBuiltInTypes.kt new file mode 100644 index 00000000000..e05bd80dc9f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/classifiersOfBuiltInTypes.kt @@ -0,0 +1,115 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KClass +import kotlin.reflect.KFunction +import kotlin.test.assertEquals + +fun primitives( + p01: Boolean, + p02: Byte, + p03: Char, + p04: Double, + p05: Float, + p06: Int, + p07: Long, + p08: Short +) {} + +fun nullablePrimitives( + p01: Boolean?, + p02: Byte?, + p03: Char?, + p04: Double?, + p05: Float?, + p06: Int?, + p07: Long?, + p08: Short? +) {} + +fun primitiveArrays( + p01: BooleanArray, + p02: ByteArray, + p03: CharArray, + p04: DoubleArray, + p05: FloatArray, + p06: IntArray, + p07: LongArray, + p08: ShortArray +) {} + +fun others( + p1: Array<*>, + p2: Array, + p3: Array?>, + p4: List<*>, + p5: List?, + p6: Map.Entry, + p7: Unit?, + p8: String, + p9: Nothing +) {} + +inline fun wrapper(): KClass = T::class + +fun check(f: KFunction<*>, vararg expected: KClass<*>) { + val actual = f.parameters.map { it.type.classifier as KClass<*> } + for ((e, a) in expected.toList().zip(actual)) { + assertEquals(e, a, "$e (${e.java}) != $a (${a.java})") + } +} + +fun box(): String { + check( + ::primitives, + Boolean::class, + Byte::class, + Char::class, + Double::class, + Float::class, + Int::class, + Long::class, + Short::class + ) + + check( + ::nullablePrimitives, + wrapper(), + wrapper(), + wrapper(), + wrapper(), + wrapper(), + wrapper(), + wrapper(), + wrapper() + ) + + check( + ::primitiveArrays, + BooleanArray::class, + ByteArray::class, + CharArray::class, + DoubleArray::class, + FloatArray::class, + IntArray::class, + LongArray::class, + ShortArray::class + ) + + check( + ::others, + Array::class, + Array::class, + Array?>::class, + List::class, + List::class, + Map.Entry::class, + Unit::class, + String::class, + Nothing::class + ) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/createType/equality.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/createType/equality.kt new file mode 100644 index 00000000000..b2ed998ab0a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/createType/equality.kt @@ -0,0 +1,43 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.full.createType +import kotlin.reflect.KTypeProjection +import kotlin.test.assertEquals +import kotlin.test.assertNotEquals + +class Foo + +fun box(): String { + assertEquals(String::class.createType(), String::class.createType()) + + assertEquals( + Foo::class.createType(listOf(KTypeProjection.STAR)), + Foo::class.createType(listOf(KTypeProjection.STAR)) + ) + + val i = Int::class.createType() + assertEquals( + Foo::class.createType(listOf(KTypeProjection.invariant(i))), + Foo::class.createType(listOf(KTypeProjection.invariant(i))) + ) + + assertNotEquals( + Foo::class.createType(listOf(KTypeProjection.contravariant(i))), + Foo::class.createType(listOf(KTypeProjection.covariant(i))) + ) + + assertNotEquals( + Foo::class.createType(listOf(KTypeProjection.covariant(Any::class.createType(nullable = true)))), + Foo::class.createType(listOf(KTypeProjection.STAR)) + ) + + assertNotEquals( + Foo::class.createType(listOf(KTypeProjection.STAR), nullable = false), + Foo::class.createType(listOf(KTypeProjection.STAR), nullable = true) + ) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/createType/innerGeneric.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/createType/innerGeneric.kt new file mode 100644 index 00000000000..3ec4b16ca33 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/createType/innerGeneric.kt @@ -0,0 +1,29 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.full.createType +import kotlin.reflect.KClass +import kotlin.reflect.KTypeProjection +import kotlin.test.assertEquals + +class A { + inner class B { + inner class C + } + class D +} + +fun foo(): A.B.C = null!! + +fun box(): String { + fun KClass<*>.inv() = KTypeProjection.invariant(this.createType()) + + val type = A.B.C::class.createType(listOf(Long::class.inv(), Double::class.inv(), Float::class.inv(), Int::class.inv())) + assertEquals("A.B.C", type.toString()) + + assertEquals("A.D", A.D::class.createType().toString()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/createType/simpleCreateType.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/createType/simpleCreateType.kt new file mode 100644 index 00000000000..a31ee1d2f9f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/createType/simpleCreateType.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.full.createType +import kotlin.reflect.KTypeProjection +import kotlin.test.assertEquals + +class Foo +class Bar + +fun box(): String { + assertEquals("Foo", Foo::class.createType().toString()) + assertEquals("Foo?", Foo::class.createType(nullable = true).toString()) + + assertEquals("Bar", Bar::class.createType(listOf(KTypeProjection.invariant(String::class.createType()))).toString()) + assertEquals("Bar?", Bar::class.createType(listOf(KTypeProjection.invariant(Int::class.createType())), nullable = true).toString()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/createType/typeParameter.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/createType/typeParameter.kt new file mode 100644 index 00000000000..db0fc185655 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/createType/typeParameter.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.full.createType +import kotlin.test.assertEquals + +class Foo { + fun nonNull(): T = null!! + fun nullable(): T? = null +} + +fun box(): String { + val tp = Foo::class.typeParameters.single() + assertEquals( + Foo::class.members.single { it.name == "nonNull" }.returnType, + tp.createType() + ) + assertEquals( + Foo::class.members.single { it.name == "nullable" }.returnType, + tp.createType(nullable = true) + ) + + assertEquals(tp.createType(), tp.createType()) + assertEquals(tp.createType(nullable = true), tp.createType(nullable = true)) + + assertEquals("T", tp.createType().toString()) + assertEquals("T?", tp.createType(nullable = true).toString()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/createType/wrongNumberOfArguments.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/createType/wrongNumberOfArguments.kt new file mode 100644 index 00000000000..834f04c1bdf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/createType/wrongNumberOfArguments.kt @@ -0,0 +1,52 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.full.createType +import kotlin.reflect.KClassifier +import kotlin.reflect.KTypeProjection + +fun test(classifier: KClassifier, arguments: List) { + try { + classifier.createType(arguments) + throw AssertionError("createType should have thrown IllegalArgumentException") + } + catch (e: IllegalArgumentException) { + // OK + } +} + +class Outer { + inner class Inner + class Nested +} + +fun box(): String { + val p = KTypeProjection.STAR + + test(String::class, listOf(p)) + test(String::class, listOf(p, p)) + test(List::class, listOf()) + test(List::class, listOf(p, p)) + test(Map::class, listOf()) + test(Map::class, listOf(p)) + test(Map::class, listOf(p, p, p)) + test(Array::class, listOf()) + + test(Outer::class, listOf()) + test(Outer::class, listOf(p, p)) + + // Outer.Inner takes two arguments: first for O, second for I + test(Outer.Inner::class, listOf()) + test(Outer.Inner::class, listOf(p)) + test(Outer.Inner::class, listOf(p, p, p)) + + // Outer.Nested takes one argument for N + test(Outer.Nested::class, listOf()) + test(Outer.Nested::class, listOf(p, p)) + + test(Outer::class.typeParameters.single(), listOf(p)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/innerGenericArguments.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/innerGenericArguments.kt new file mode 100644 index 00000000000..66f84b13eae --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/innerGenericArguments.kt @@ -0,0 +1,35 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.test.* + +class Outer { + inner class Inner { + inner class Innermost + } +} + +fun foo(): Outer.Inner.Innermost = null!! + +fun box(): String { + val types = ::foo.returnType.arguments.map { it.type!! } + + assertEquals( + listOf( + Any::class, + Any::class, + String::class, + Float::class, + Int::class, + Number::class + ), + types.map { it.classifier } + ) + + assertFalse(types[0].isMarkedNullable) + assertTrue(types[1].isMarkedNullable) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/jvmErasureOfClass.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/jvmErasureOfClass.kt new file mode 100644 index 00000000000..87c35586db6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/jvmErasureOfClass.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.jvmErasure +import kotlin.test.assertEquals + +fun string(): String = null!! +fun array(): Array = null!! + +fun collection(): Collection = null!! +fun mutableCollection(): MutableCollection = null!! + +fun box(): String { + assertEquals(String::class, ::string.returnType.jvmErasure) + assertEquals(Array::class, ::array.returnType.jvmErasure) + + assertEquals(Collection::class, ::collection.returnType.jvmErasure) + assertEquals(MutableCollection::class, ::mutableCollection.returnType.jvmErasure) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/jvmErasureOfTypeParameter.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/jvmErasureOfTypeParameter.kt new file mode 100644 index 00000000000..5112e8e0b6f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/jvmErasureOfTypeParameter.kt @@ -0,0 +1,48 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.jvm.jvmErasure +import kotlin.reflect.KClass +import kotlin.test.assertEquals + +open class O + +class A { + fun simple(): T = null!! + fun string(): T = null!! + fun nullableString(): T = null!! + fun otherTypeParameter(): T = null!! + fun > otherTypeParameterWithBound(): T = null!! + + fun twoInterfaces1(): T where T : Comparable<*> = null!! + fun > twoInterfaces2(): T where T : Cloneable = null!! + fun interfaceAndClass1(): T where T : O = null!! + fun interfaceAndClass2(): T where T : Cloneable = null!! + + fun arrayOfAny(): Array = null!! + fun arrayOfNumber(): Array = null!! + fun arrayOfArrayOfCloneable(): Array> where T : Cloneable, T : Comparable<*> = null!! +} + +fun get(name: String): KClass<*> = A::class.members.single { it.name == name }.returnType.jvmErasure + +fun box(): String { + assertEquals(Any::class, get("simple")) + assertEquals(String::class, get("string")) + assertEquals(String::class, get("nullableString")) + assertEquals(Any::class, get("otherTypeParameter")) + assertEquals(List::class, get("otherTypeParameterWithBound")) + + assertEquals(Cloneable::class, get("twoInterfaces1")) + assertEquals(Comparable::class, get("twoInterfaces2")) + assertEquals(O::class, get("interfaceAndClass1")) + assertEquals(O::class, get("interfaceAndClass2")) + + assertEquals(Array::class, get("arrayOfAny")) + assertEquals(Array::class, get("arrayOfNumber")) + assertEquals(Array>::class, get("arrayOfArrayOfCloneable")) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/platformTypeClassifier.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/platformTypeClassifier.kt new file mode 100644 index 00000000000..8487647d634 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/platformTypeClassifier.kt @@ -0,0 +1,39 @@ +// TARGET_BACKEND: JVM + +// WITH_REFLECT +// FILE: J.java + +import java.util.List; + +public class J { + public static String string() { + return ""; + } + + public static List list() { + return null; + } + + public static int primitiveInt() { + return 0; + } + + public static Integer wrapperInt() { + return 0; + } +} + +// FILE: K.kt + +import kotlin.reflect.KClass +import kotlin.test.assertEquals + +fun box(): String { + assertEquals(String::class, J::string.returnType.classifier) + assertEquals(List::class, J::list.returnType.classifier) + + assertEquals(Int::class.javaPrimitiveType!!, (J::primitiveInt.returnType.classifier as KClass<*>).java) + assertEquals(Int::class.javaObjectType, (J::wrapperInt.returnType.classifier as KClass<*>).java) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/platformTypeNotEqualToKotlinType.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/platformTypeNotEqualToKotlinType.kt new file mode 100644 index 00000000000..556607a12de --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/platformTypeNotEqualToKotlinType.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public class J { + public static String foo() { + return ""; + } +} + +// FILE: K.kt + +import kotlin.test.assertNotEquals + +fun nonNullString(): String = "" +fun nullableString(): String? = "" + +fun box(): String { + assertNotEquals(J::foo.returnType, ::nonNullString.returnType) + assertNotEquals(J::foo.returnType, ::nullableString.returnType) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/platformTypeToString.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/platformTypeToString.kt new file mode 100644 index 00000000000..e339364b397 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/platformTypeToString.kt @@ -0,0 +1,27 @@ +// TARGET_BACKEND: JVM + +// WITH_REFLECT +// FILE: J.java + +import java.util.List; + +public class J { + public static String string() { + return ""; + } + + public static List list() { + return null; + } +} + +// FILE: K.kt + +import kotlin.test.assertEquals + +fun box(): String { + assertEquals("kotlin.String!", J::string.returnType.toString()) + assertEquals("kotlin.collections.(Mutable)List!", J::list.returnType.toString()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/subtyping/platformType.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/subtyping/platformType.kt new file mode 100644 index 00000000000..0242d6febfd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/subtyping/platformType.kt @@ -0,0 +1,35 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public interface J { + String platformString(); +} + +// FILE: K.kt + +import kotlin.reflect.KCallable +import kotlin.reflect.full.* +import kotlin.test.assertTrue + +fun string(): String = null!! +fun nullableString(): String? = null!! + +fun check(subCallable: KCallable<*>, superCallable: KCallable<*>) { + val subtype = subCallable.returnType + val supertype = superCallable.returnType + assertTrue(subtype.isSubtypeOf(supertype)) + assertTrue(supertype.isSupertypeOf(subtype)) +} + +fun box(): String { + check(::string, J::platformString) + check(J::platformString, ::string) + check(::nullableString, J::platformString) + check(J::platformString, ::nullableString) + check(J::platformString, J::platformString) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/subtyping/simpleGenericTypes.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/subtyping/simpleGenericTypes.kt new file mode 100644 index 00000000000..ff0e3b290d6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/subtyping/simpleGenericTypes.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.full.* +import kotlin.test.assertTrue +import kotlin.test.assertFalse + +open class G +class A : G() + +fun gOfString(): G = null!! +fun gOfInt(): G = null!! + +fun box(): String { + val gs = ::gOfString.returnType + val gi = ::gOfInt.returnType + val a = ::A.returnType + + assertTrue(a.isSubtypeOf(gs)) + assertTrue(gs.isSupertypeOf(a)) + + assertFalse(a.isSubtypeOf(gi)) + assertFalse(gi.isSupertypeOf(a)) + + assertFalse(gs.isSubtypeOf(gi)) + assertFalse(gs.isSupertypeOf(gi)) + assertFalse(gi.isSubtypeOf(gs)) + assertFalse(gi.isSupertypeOf(gs)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/subtyping/simpleSubtypeSupertype.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/subtyping/simpleSubtypeSupertype.kt new file mode 100644 index 00000000000..ac0b42bd669 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/subtyping/simpleSubtypeSupertype.kt @@ -0,0 +1,68 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KCallable +import kotlin.reflect.full.* +import kotlin.test.assertTrue +import kotlin.test.assertFalse + +fun check(subCallable: KCallable<*>, superCallable: KCallable<*>, shouldBeSubtype: Boolean) { + val subtype = subCallable.returnType + val supertype = superCallable.returnType + if (shouldBeSubtype) { + assertTrue(subtype.isSubtypeOf(supertype)) + assertTrue(supertype.isSupertypeOf(subtype)) + } else { + assertFalse(subtype.isSubtypeOf(supertype)) + assertFalse(supertype.isSupertypeOf(subtype)) + } +} + +open class O +class X : O() + +fun any(): Any = null!! +fun string(): String = null!! +fun nullableString(): String? = null!! +fun int(): Int = null!! +fun nothing(): Nothing = null!! +fun nullableNothing(): Nothing? = null!! +fun function2(): (Any, Any) -> Any = null!! +fun function3(): (Any, Any, Any) -> Any = null!! + +fun box(): String { + check(::any, ::any, true) + check(::int, ::int, true) + check(::nothing, ::nothing, true) + check(::nullableNothing, ::nullableNothing, true) + + check(::string, ::any, true) + check(::nullableString, ::any, false) + check(::int, ::any, true) + check(::O, ::any, true) + check(::X, ::any, true) + + check(::nothing, ::any, true) + check(::nothing, ::string, true) + check(::nothing, ::nullableString, true) + check(::nullableNothing, ::nullableString, true) + check(::nullableNothing, ::string, false) + + check(::string, ::nullableString, true) + check(::nullableString, ::string, false) + + check(::X, ::O, true) + check(::O, ::X, false) + + check(::int, ::string, false) + check(::string, ::int, false) + check(::any, ::string, false) + check(::any, ::nullableString, false) + + check(::function2, ::function3, false) + check(::function3, ::function2, false) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/subtyping/typeProjection.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/subtyping/typeProjection.kt new file mode 100644 index 00000000000..586b6d6b036 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/subtyping/typeProjection.kt @@ -0,0 +1,44 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.full.isSubtypeOf +import kotlin.test.assertTrue +import kotlin.test.assertFalse + +class G + +fun number(): G = null!! +fun outNumber(): G = null!! +fun inNumber(): G = null!! +fun star(): G<*> = null!! + +fun box(): String { + val n = ::number.returnType + val o = ::outNumber.returnType + val i = ::inNumber.returnType + val st = ::star.returnType + + // G <: G + assertTrue(n.isSubtypeOf(o)) + assertFalse(o.isSubtypeOf(n)) + + // G <: G + assertTrue(n.isSubtypeOf(i)) + assertFalse(i.isSubtypeOf(n)) + + // G <: G<*> + assertTrue(n.isSubtypeOf(st)) + assertFalse(st.isSubtypeOf(n)) + + // G <: G<*> + assertTrue(o.isSubtypeOf(st)) + assertFalse(st.isSubtypeOf(o)) + + // G <: G<*> + assertTrue(i.isSubtypeOf(st)) + assertFalse(st.isSubtypeOf(i)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/typeArguments.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/typeArguments.kt new file mode 100644 index 00000000000..c07bd52d723 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/typeArguments.kt @@ -0,0 +1,45 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KTypeProjection +import kotlin.reflect.KVariance +import kotlin.test.assertEquals + +fun string(): String = null!! + +class Fourple +fun projections(): Fourple = null!! + +fun array(): Array = null!! + +fun list(): List = null!! + +fun box(): String { + val string = ::string.returnType + assertEquals(listOf(), string.arguments) + + assertEquals( + listOf( + KTypeProjection.invariant(string), + KTypeProjection.contravariant(string), + KTypeProjection.covariant(string), + KTypeProjection.STAR + ), + ::projections.returnType.arguments + ) + assertEquals( + listOf(string, string, string, null), + ::projections.returnType.arguments.map(KTypeProjection::type) + ) + + val outNumber = ::array.returnType.arguments.single() + assertEquals(KVariance.OUT, outNumber.variance) + assertEquals(Number::class, outNumber.type?.classifier) + + // There should be no use-site variance, despite the fact that the corresponding parameter has 'out' variance + assertEquals(KVariance.INVARIANT, ::list.returnType.arguments.single().variance) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/useSiteVariance.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/useSiteVariance.kt new file mode 100644 index 00000000000..be511cd44db --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/useSiteVariance.kt @@ -0,0 +1,29 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT + +import kotlin.reflect.KVariance +import kotlin.test.assertEquals + +class Fourple +fun foo(): Fourple = null!! + +fun listOfStrings(): List = null!! + +fun box(): String { + assertEquals( + listOf( + KVariance.INVARIANT, + KVariance.IN, + KVariance.OUT, + null + ), + ::foo.returnType.arguments.map { it.variance } + ) + + // Declaration-site variance should have no effect on the variance of the type projection: + assertEquals(KVariance.INVARIANT, ::listOfStrings.returnType.arguments.first().variance) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reflection/types/withNullability.kt b/backend.native/tests/external/codegen/blackbox/reflection/types/withNullability.kt new file mode 100644 index 00000000000..34cd04295a9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reflection/types/withNullability.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_REFLECT +// FILE: J.java + +public interface J { + String platform(); +} + +// FILE: K.kt + +import kotlin.reflect.full.withNullability +import kotlin.test.assertEquals + +fun nonNull(): String = "" +fun nullable(): String? = "" + +fun box(): String { + val nonNull = ::nonNull.returnType + val nullable = ::nullable.returnType + val platform = J::platform.returnType + + assertEquals(nonNull, nullable.withNullability(false)) + assertEquals(nullable, nullable.withNullability(true)) + assertEquals(nonNull, nonNull.withNullability(false)) + assertEquals(nullable, nonNull.withNullability(true)) + + assertEquals(nonNull, platform.withNullability(false)) + assertEquals(nullable, platform.withNullability(true)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/Kt1149.kt b/backend.native/tests/external/codegen/blackbox/regressions/Kt1149.kt new file mode 100644 index 00000000000..f1581c61cf7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/Kt1149.kt @@ -0,0 +1,19 @@ +// WITH_RUNTIME + +package test.regressions.kt1149 + +public interface SomeTrait { + fun foo() +} + +fun box(): String { + val list = ArrayList() + var res = ArrayList() + list.add(object : SomeTrait { + override fun foo() { + res.add("anonymous.foo()") + } + }) + list.forEach{ it.foo() } + return if ("anonymous.foo()" == res[0]) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/Kt1619Test.kt b/backend.native/tests/external/codegen/blackbox/regressions/Kt1619Test.kt new file mode 100644 index 00000000000..d8f38f37765 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/Kt1619Test.kt @@ -0,0 +1,19 @@ +// WITH_RUNTIME + +package regressions + +class Kt1619Test { + + fun doSomething(list: List): Int { + return list.size + } + + fun testCollectionNotNullCanBeUsedForNullables(): Int { + val list: List = arrayListOf("foo", "bar") + return doSomething(list) + } +} + +fun box(): String { + return if (Kt1619Test().testCollectionNotNullCanBeUsedForNullables() == 2) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/Kt2495Test.kt b/backend.native/tests/external/codegen/blackbox/regressions/Kt2495Test.kt new file mode 100644 index 00000000000..072eba9a2f8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/Kt2495Test.kt @@ -0,0 +1,17 @@ +// WITH_RUNTIME + +package regressions + +fun f(xs: Iterator): Int { + var answer = 0 + for (x in xs) { + answer += x + } + return answer +} + +fun box(): String { + val list = arrayListOf(1, 2, 3) + val result = f(list.iterator()) + return if (6 == result) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/arrayLengthNPE.kt b/backend.native/tests/external/codegen/blackbox/regressions/arrayLengthNPE.kt new file mode 100644 index 00000000000..e3c91e64aaf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/arrayLengthNPE.kt @@ -0,0 +1,13 @@ +// See KT-14242 +var x = 1 +fun box(): String { + val testArray: Array? = when (1) { + x -> null + else -> arrayOfNulls(0) + } + + // Must not be NPE here + val size = testArray?.size + + return size?.toString() ?: "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/collections.kt b/backend.native/tests/external/codegen/blackbox/regressions/collections.kt new file mode 100644 index 00000000000..91779c31220 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/collections.kt @@ -0,0 +1,154 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +package collections + +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue +import java.security.KeyPair + + +fun testCollectionSize(c: Collection) = assertEquals(0, c.size) +fun testCollectionIsEmpty(c: Collection) = assertTrue(c.isEmpty()) +fun testCollectionContains(c: Collection) = assertTrue(c.contains(1 as Any?)) +fun testCollectionIterator(c: Collection) { + val it = c.iterator() + while (it.hasNext()) { + assertEquals(1, it.next() as Any?) + } +} +fun testCollectionContainsAll(c: Collection) = assertTrue(c.containsAll(c)) +fun testMutableCollectionAdd(c: MutableCollection, t: T) { + c.add(t) + assertEquals(1, c.size) + assertTrue(c.contains(t)) +} +fun testMutableCollectionRemove(c: MutableCollection, t: T) { + c.remove(t) + assertEquals(0, c.size) + assertFalse(c.contains(t)) +} +fun testMutableCollectionIterator(c: MutableCollection, t: T) { + c.add(t) + val it = c.iterator() + while (it.hasNext()) { + it.next() + it.remove() + } + assertEquals(0, c.size) +} +fun testMutableCollectionAddAll(c: MutableCollection, t1: T, t2: T) { + c.addAll(arrayListOf(t1, t2)) + assertEquals(arrayListOf(t1, t2), c) +} +fun testMutableCollectionRemoveAll(c: MutableCollection, t1: T, t2: T) { + c.addAll(arrayListOf(t1, t2)) + c.removeAll(arrayListOf(t1)) + assertEquals(arrayListOf(t2), c) +} +fun testMutableCollectionRetainAll(c: MutableCollection, t1: T, t2: T) { + c.addAll(arrayListOf(t1, t2)) + c.retainAll(arrayListOf(t1)) + assertEquals(arrayListOf(t1), c) +} +fun testMutableCollectionClear(c: MutableCollection) { + c.clear() + assertTrue(c.isEmpty()) +} + +fun testCollection() { + testCollectionSize(arrayListOf()) + testCollectionIsEmpty(arrayListOf()) + testCollectionContains(arrayListOf(1)) + testCollectionIterator(arrayListOf(1)) + testCollectionContainsAll(arrayListOf("a", "b")) + + testMutableCollectionAdd(arrayListOf(), "") + testMutableCollectionRemove(arrayListOf("a"), "a") + testMutableCollectionIterator(arrayListOf(), 1) + testMutableCollectionAddAll(arrayListOf(), 1, 2) + testMutableCollectionRemoveAll(arrayListOf(), 1, 2) + testMutableCollectionRetainAll(arrayListOf(), 1, 2) + testMutableCollectionClear(arrayListOf(1, 2)) +} + + +fun testListGet(l: List, t: T) = assertEquals(t, l.get(0)) +fun testListIndexOf(l: List, t: T) = assertEquals(0, l.indexOf(t)) +fun testListIterator(l: List, t1 : T, t2 : T) { + val indexes = arrayListOf() + val result = arrayListOf() + val it = l.listIterator() + while (it.hasNext()) { + indexes.add(it.nextIndex()) + result.add(it.next()) + } + while (it.hasPrevious()) { + indexes.add(it.previousIndex()) + result.add(it.previous()) + } + assertEquals(arrayListOf(0, 1, 1, 0), indexes) + assertEquals(arrayListOf(t1, t2, t2, t1), result) +} +fun testListSublist(l: List, t: T) = assertEquals(arrayListOf(t), l.subList(0, 1)) + +fun testMutableListSet(l: MutableList, t: T) { + l.set(0, t) + assertEquals(arrayListOf(t), l) +} +fun testMutableListIterator(l: MutableList, t1: T, t2: T, t3: T) { + val it = l.listIterator() + while (it.hasNext()) { + it.next() + it.add(t3) + } + assertEquals(arrayListOf(t1, t3, t2, t3), l) +} + +fun testList() { + testListGet(arrayListOf(1), 1) + testListIndexOf(arrayListOf(1), 1) + testListIterator(arrayListOf("a", "b"), "a", "b") + testListSublist(arrayListOf(1, 2), 1) + + testMutableListSet(arrayListOf(2), 4) + testMutableListIterator(arrayListOf(1, 2), 1, 2, 3) +} + +fun testMapContainsKey(map: Map, k: K) = assertTrue(map.containsKey(k)) +fun testMapKeys(map: Map, k1: K, k2: K) = assertEqualCollections(hashSetOf(k1, k2), map.keys) +fun testMapValues(map: Map, v1: V, v2: V) = assertEqualCollections(hashSetOf(v1, v2), map.values) +fun testMapEntrySet(map: Map, k : K, v: V) { + for (entry in map.entries) { + assertEquals(k, entry.key) + assertEquals(v, entry.value) + } +} +fun testMutableMapEntry(map: MutableMap, k1 : K, v: V) { + for (entry in map.entries) { + entry.setValue(v) + } + assertEquals(hashMapOf(k1 to v), map) +} + + +fun testMap() { + testMapContainsKey(hashMapOf(1 to 'a', 2 to 'b'), 2) + testMapKeys(hashMapOf(1 to 'a', 2 to 'b'), 1, 2) + testMapValues(hashMapOf(1 to 'a', 2 to 'b'), 'a', 'b') + testMapEntrySet(hashMapOf(1 to 'a'), 1, 'a') + testMutableMapEntry(hashMapOf(1 to 'a'), 1, 'b') +} + +fun box() : String { + testCollection() + testList() + testMap() + return "OK" +} + +fun assertEqualCollections(c1: Collection, c2: Collection) = assertEquals(c1.toCollection(hashSetOf()), c2.toCollection(hashSetOf())) diff --git a/backend.native/tests/external/codegen/blackbox/regressions/commonSupertypeContravariant.kt b/backend.native/tests/external/codegen/blackbox/regressions/commonSupertypeContravariant.kt new file mode 100644 index 00000000000..8fb7e750367 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/commonSupertypeContravariant.kt @@ -0,0 +1,11 @@ +interface In + +class En : In +class A : In +fun select(x: T, y: T): T = x ?: y + +// This test just checks that no internal error happens in backend +// Return type should be In<*> nor In +fun foobar(e: En<*>) = select(A(), e) + +fun box() = "OK" diff --git a/backend.native/tests/external/codegen/blackbox/regressions/commonSupertypeContravariant2.kt b/backend.native/tests/external/codegen/blackbox/regressions/commonSupertypeContravariant2.kt new file mode 100644 index 00000000000..959eaf527aa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/commonSupertypeContravariant2.kt @@ -0,0 +1,9 @@ +interface In +class A : In +class B : In +fun select(x: T, y: T) = x ?: y + +// This test just checks that no internal error happens in backend +fun foobar(a: A, b: B) = select(a, b) + +fun box() = "OK" diff --git a/backend.native/tests/external/codegen/blackbox/regressions/doubleMerge.kt b/backend.native/tests/external/codegen/blackbox/regressions/doubleMerge.kt new file mode 100644 index 00000000000..92e282fab33 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/doubleMerge.kt @@ -0,0 +1,10 @@ +fun foo(): Double { + var d = 2.0 + if (d > 0.0) { + d++ + } + d++ + return d +} + +fun box() = if (foo() > 3.5) "OK" else "Fail" diff --git a/backend.native/tests/external/codegen/blackbox/regressions/floatMerge.kt b/backend.native/tests/external/codegen/blackbox/regressions/floatMerge.kt new file mode 100644 index 00000000000..22033fa3950 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/floatMerge.kt @@ -0,0 +1,10 @@ +fun foo(): Float { + var f = 2.0f + if (f > 0.0f) { + f++ + } + f++ + return f +} + +fun box() = if (foo() > 3.5f) "OK" else "Fail" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/regressions/generic.kt b/backend.native/tests/external/codegen/blackbox/regressions/generic.kt new file mode 100644 index 00000000000..c5cf2b2efff --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/generic.kt @@ -0,0 +1,21 @@ +// WITH_RUNTIME + +fun ArrayList.findAll(predicate: (T) -> Boolean): ArrayList { + val result = ArrayList() + for(t in this) { + if (predicate(t)) result.add(t) + } + return result +} + + +fun box(): String { + val list: ArrayList = ArrayList() + list.add("Prague") + list.add("St.Petersburg") + list.add("Moscow") + list.add("Munich") + + val m: ArrayList = list.findAll({ name: String -> name.startsWith("M")}) + return if (m.size == 2) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/getGenericInterfaces.kt b/backend.native/tests/external/codegen/blackbox/regressions/getGenericInterfaces.kt new file mode 100644 index 00000000000..a0c9fe398e7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/getGenericInterfaces.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// KT-4485 getGenericInterfaces vs getInterfaces for kotlin classes + +class SimpleClass + +class ClassWithNonGenericSuperInterface: Cloneable + +class ClassWithGenericSuperInterface: java.util.Comparator { + override fun compare(a: String, b: String): Int = 0 +} + +fun check(klass: Class<*>) { + val interfaces = klass.getInterfaces().toList() + val genericInterfaces = klass.getGenericInterfaces().toList() + if (interfaces.size != genericInterfaces.size) { + throw AssertionError("interfaces=$interfaces, genericInterfaces=$genericInterfaces") + } +} + +fun box(): String { + check(SimpleClass::class.java) + check(ClassWithNonGenericSuperInterface::class.java) + check(ClassWithGenericSuperInterface::class.java) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/hashCodeNPE.kt b/backend.native/tests/external/codegen/blackbox/regressions/hashCodeNPE.kt new file mode 100644 index 00000000000..d362db21e77 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/hashCodeNPE.kt @@ -0,0 +1,13 @@ +// See KT-14242 +var x = 1 +fun box(): String { + val any: Any? = when (1) { + x -> null + else -> Any() + } + + // Must not be NPE here + val hashCode = any?.hashCode() + + return hashCode?.toString() ?: "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/internalTopLevelOtherPackage.kt b/backend.native/tests/external/codegen/blackbox/regressions/internalTopLevelOtherPackage.kt new file mode 100644 index 00000000000..8c51a9a2cf9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/internalTopLevelOtherPackage.kt @@ -0,0 +1,9 @@ +// FILE: 1.kt + +fun box() = a.x + +// FILE: 2.kt + +package a + +internal val x: String = "OK" diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt10143.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt10143.kt new file mode 100644 index 00000000000..33a0cbbce16 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt10143.kt @@ -0,0 +1,33 @@ +// FILE: Outer.kt + +package another +open class Outer { + protected class Stage(val run: () -> Unit) + protected class My(var stage: Stage? = null) { + fun initStage(f: () -> Unit): Stage { + stage = Stage(f) + return stage!! + } + } + protected fun my(init: My.() -> Unit): My { + val result = My() + result.init() + return result + } +} + +// FILE: Main.kt + +package other +class Derived : another.Outer() { + init { + my { + initStage { } + } + } +} + +fun box(): String { + Derived() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt10934.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt10934.kt new file mode 100644 index 00000000000..bbc549b99c4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt10934.kt @@ -0,0 +1,38 @@ +//KT-10934 compiler throws UninferredParameterTypeConstructor in when block that covers all types + +class Parser(val f: (TInput) -> Result) { + + operator fun invoke(input: TInput): Result = f(input) + + fun mapJoin( + selector: (TValue) -> Parser, + projector: (TValue, TIntermediate) -> TValue2 + ): Parser { + return Parser({ input -> + val res = this(input) + when (res) { + is Result.ParseError -> Result.ParseError(res.productionLabel, res.child, res.rest) + is Result.Value -> { + val v = res.value + val res2 = selector(v)(res.rest) + when (res2) { + is Result.ParseError -> Result.ParseError(res2.productionLabel, res2.child, res2.rest) + is Result.Value -> Result.Value(projector(v, res2.value), res2.rest) + } + } + } + }) + } +} + +/** A parser can return one of two Results */ +sealed class Result { + + class Value(val value: TValue, val rest: TInput) : Result() {} + + class ParseError(val productionLabel: String, + val child: ParseError?, + val rest: TInput) : Result() {} +} + +fun box() = "OK" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt1172.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt1172.kt new file mode 100644 index 00000000000..feaa0290dad --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt1172.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE +// not sure if it's ok to change Object to Any + +// WITH_RUNTIME + +package test.regressions.kt1172 + +public fun scheduleRefresh(vararg files : Object) { + ArrayList(files.map { it }) +} + +fun box(): String { + scheduleRefresh() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt1202.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt1202.kt new file mode 100644 index 00000000000..139bfc770bf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt1202.kt @@ -0,0 +1,122 @@ +// TARGET_BACKEND: JVM + +// WITH_RUNTIME +// FULL_JDK + +package testeval + +import java.util.LinkedList +import java.util.Deque + +interface Expression +class Num(val value : Int) : Expression +class Sum(val left : Expression, val right : Expression) : Expression +class Mult(val left : Expression, val right : Expression) : Expression + +fun eval(e : Expression) : Int { + return when (e) { + is Num -> e.value + is Sum -> eval(e.left) + eval (e.right) + is Mult -> eval(e.left) * eval (e.right) + else -> throw AssertionError("Unknown expression") + } +} + +interface ParseResult { + val success : Boolean + val value : T +} + +class Success(override val value : T) : ParseResult { + public override val success : Boolean = true +} + +class Failure(val message : String) : ParseResult { + override val success = false + override val value : Nothing = throw UnsupportedOperationException("Don't call value on a Failure") +} + +open class Token(val text : String) { + override fun toString() = text +} +object LPAR : Token("(") +object RPAR : Token(")") +object PLUS : Token("+") +object TIMES : Token("*") +object EOF : Token("EOF") +class Number(text : String) : Token(text) +class Error(text : String) : Token("[Error: $text]") + + +fun tokenize(text : String) : Deque { + val result = LinkedList() + for (c in text) { + result.add(when (c) { + '(' -> LPAR + ')' -> RPAR + '+' -> PLUS + '*' -> TIMES + in '0'..'9' -> Number(c.toString()) + else -> Error(c.toString()) + }) + } + result.add(EOF) + return result +} + +fun parseSum(tokens : Deque) : ParseResult { + val left = parseMult(tokens) + if (!left.success) return left + + if (tokens.peek() == PLUS) { + tokens.pop() + val right = parseSum(tokens) + if (!right.success) return right + return Success(Sum(left.value, right.value)) + } + + return left +} + +fun parseMult(tokens : Deque) : ParseResult { + val left = parseAtomic(tokens) + if (!left.success) return left + + if (tokens.peek() == PLUS) { + tokens.pop() + val right = parseMult(tokens) + if (!right.success) return right + return Success(Mult(left.value, right.value)) + } + + return left +} + +fun parseAtomic(tokens : Deque) : ParseResult { + val token = tokens.poll() + return when (token) { + LPAR -> { + val result = parseSum(tokens) + val rpar = tokens.poll() + if (rpar == RPAR) + result + else + Failure("Expecting ')'") + } + is Number -> Success(Num(Integer.parseInt((token as Token).text))) + else -> Failure("Unexpected EOF") + } +} + +fun parse(text : String) : ParseResult = parseSum(tokenize(text)) + +fun box(): String { + if (1 != eval(Num(1))) return "fail 1" + if (2 != eval(Sum(Num(1), Num(1)))) return "fail 2" + if (3 != eval(Mult(Num(3), Num(1)))) return "fail 3" + if (6 != eval(Mult(Num(3), Sum(Num(1), Num(1))))) return "fail 4" + + if (1 != eval(parse("1").value)) return "fail 5" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt13381.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt13381.kt new file mode 100644 index 00000000000..b424d596455 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt13381.kt @@ -0,0 +1,12 @@ +interface A { + // There must be no delegation methods for 'log' and 'bar' in C as they are private + private val log: String get() = "O" + private fun bar() = "K" + + fun foo() = log + bar() +} + +interface B : A +class C : B + +fun box() = C().foo() diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt1406.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt1406.kt new file mode 100644 index 00000000000..171a734bec8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt1406.kt @@ -0,0 +1,29 @@ +// TARGET_BACKEND: JVM + +// WITH_RUNTIME +// FULL_JDK + +package pack + +import java.util.regex.Pattern + +class C{ + public fun foo(){ + val items : Collection = listOf(Item()) + val result = ArrayList() + val pattern: Pattern? = Pattern.compile("...") + items.filterTo(result) { + pattern!!.matcher(it.name())!!.matches() + } + } + + private fun Item.name() : String = "" +} + +class Item{ +} + +fun box() : String { + C().foo() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt14447.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt14447.kt new file mode 100644 index 00000000000..7aab4c5003b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt14447.kt @@ -0,0 +1,22 @@ +class ImpulsMigration +{ + fun migrate(oldVersion: Long) + { + var _oldVersion = oldVersion + + if (4 > 3) + { + _oldVersion = 1 + } + + if (1 > 3) + { + _oldVersion++ + } + } +} + +fun box(): String { + ImpulsMigration().migrate(1L) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt1515.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt1515.kt new file mode 100644 index 00000000000..038e7120483 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt1515.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: 1.kt + +package thispackage + +import otherpackage.* + +fun box(): String { + if (!localUse()) { + return "local use failed" + } + if (!fromOtherPackage()) { + return "use from other package failed" + } + return "OK" +} + +fun localUse(): Boolean { + val c = Runnable::class.java + return (c.getName()!! == "java.lang.Runnable") +} + +// FILE: 2.kt + +package otherpackage + +fun fromOtherPackage(): Boolean { + val c = Runnable::class.java + return (c.getName()!! == "java.lang.Runnable") +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt1528.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt1528.kt new file mode 100644 index 00000000000..99352a01acb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt1528.kt @@ -0,0 +1,10 @@ +// FILE: 1.kt + +fun box() = foo() + +// FILE: 2.kt + +private val a = "OK" +fun foo() : String { + return "${a}" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt1568.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt1568.kt new file mode 100644 index 00000000000..e9f44796815 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt1568.kt @@ -0,0 +1,9 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box() : String { + val i = 1 + return if(i.javaClass.getSimpleName() == "int") "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt1779.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt1779.kt new file mode 100644 index 00000000000..ffcb7d79844 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt1779.kt @@ -0,0 +1,20 @@ +// WITH_RUNTIME + +import kotlin.collections.AbstractIterator + +class MyIterator : AbstractIterator() { + var i = 0 + public override fun computeNext() { + if(i < 5) + setNext((i++).toString()) + } + +} + +fun box() : String { + var k = "" + for (x in MyIterator()) { + k+=x + } + return if(k=="01234") "OK" else k +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt1800.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt1800.kt new file mode 100644 index 00000000000..85b88bbac74 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt1800.kt @@ -0,0 +1,30 @@ +// WITH_RUNTIME +//KT-1800 error/NonExistentClass generated on runtime +package i + +public class User(val firstName: String, + val lastName: String, + val age: Int) { + override fun toString() = "$firstName $lastName, age $age" +} + +public fun > Collection.testMin(): T? { + var minValue: T? = null + for(value in this) { + if (minValue == null || value.compareTo(minValue!!) < 0) { + minValue = value + } + } + return minValue +} + +fun box() : String { + val users = arrayListOf( + User("John", "Doe", 30), + User("Jane", "Doe", 27)) + + val ages = users.map { it.age } + + val minAge = ages.testMin() + return if (minAge == 27) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt1845.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt1845.kt new file mode 100644 index 00000000000..1451484226a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt1845.kt @@ -0,0 +1,12 @@ +// FILE: 1.kt + +public var v1: String = "V1" + +fun box(): String { + val s = "v1: $v1, v2: $v2" + return "OK" +} + +// FILE: 2.kt + +public var v2: String = "V2" diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt1932.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt1932.kt new file mode 100644 index 00000000000..1404fde6962 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt1932.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import java.lang.annotation.Annotation + +@Retention(AnnotationRetention.RUNTIME) +annotation class foo(val name : String) + +class Test() { + @foo("OK") fun hello(input : String) { + } +} + +fun box(): String { + val test = Test() + for (method in Test::class.java.getMethods()!!) { + val anns = method?.getAnnotations() as Array + if (!anns.isEmpty()) { + for (ann in anns) { + val fooAnn = ann as foo + return fooAnn.name + } + } + } + return "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt2017.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt2017.kt new file mode 100644 index 00000000000..3b1b64b5dc1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt2017.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME + +fun box(): String { + val sorted = arrayListOf("1", "3", "2").sorted() + return if (sorted != arrayListOf("1", "2", "3")) "$sorted" else "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt2060.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt2060.kt new file mode 100644 index 00000000000..374e73111fb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt2060.kt @@ -0,0 +1,28 @@ +// FILE: 1.kt + +import testing.ClassWithInternals + +public class HelloServer() : ClassWithInternals() { + public override fun start() { + val test = foo() + someGetter //+ some + } +} + +fun box() : String { + HelloServer().start() + return "OK" +} + +// FILE: 2.kt + +package testing; // There is no error if both files are in default package + +public abstract class ClassWithInternals { + protected var some: Int = 0; + protected var someGetter: Int = 0 + get() = 5 + + protected fun foo() : Int = 0 + + public abstract fun start() : Unit; +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt2210.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt2210.kt new file mode 100644 index 00000000000..95f4d64882a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt2210.kt @@ -0,0 +1,8 @@ +class A(t: Array>) { + val a:Array> = t +} + +fun box(): String { + A(arrayOf()) // <- java.lang.VerifyError: (class: A, method: getA signature: ()[[Ljava/lang/Object;) Wrong return type in function + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt2246.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt2246.kt new file mode 100644 index 00000000000..e03cc3155fc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt2246.kt @@ -0,0 +1,9 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String { + kotlin.assert(true) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt2318.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt2318.kt new file mode 100644 index 00000000000..21d87c5e022 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt2318.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String { + Boolean::class.java + Byte::class.java + Short::class.java + Char::class.java + Int::class.java + Long::class.java + Float::class.java + Double::class.java + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt2509.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt2509.kt new file mode 100644 index 00000000000..10529d6d497 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt2509.kt @@ -0,0 +1,12 @@ +fun box(): String { + A() + return "OK" +} + +class A: B() { + override var foo = arrayOf(12, 13) +} + +abstract class B { + abstract var foo: Array +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt2593.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt2593.kt new file mode 100644 index 00000000000..cee437b0d37 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt2593.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun foo() { + if (1==1) { + 1.javaClass + } else { + } +} + +fun box() = "OK" diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt274.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt274.kt new file mode 100644 index 00000000000..d6393b5578a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt274.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +fun box() : String { + val vector = java.util.Vector() + vector.add(1) + vector.add(2) + vector.add(3) + + var sum = 0 + for(e in vector.elements()) { + sum += e + } + return if(sum == 6) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt3046.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt3046.kt new file mode 100644 index 00000000000..ffdc39f27de --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt3046.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String { + val bool = true + if (bool.javaClass != Boolean::class.java) return "javaClass function on boolean fails" + val b = 1.toByte() + if (b.javaClass != Byte::class.java) return "javaClass function on byte fails" + val s = 1.toShort() + if (s.javaClass != Short::class.java) return "javaClass function on short fails" + val c = 'c' + if (c.javaClass != Char::class.java) return "javaClass function on char fails" + val i = 1 + if (i.javaClass != Int::class.java) return "javaClass function on int fails" + val l = 1.toLong() + if (l.javaClass != Long::class.java) return "javaClass function on long fails" + val f = 1.toFloat() + if (f.javaClass != Float::class.java) return "javaClass function on float fails" + val d = 1.0 + if (d.javaClass != Double::class.java) return "javaClass function on double fails" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt3107.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt3107.kt new file mode 100644 index 00000000000..851d6931058 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt3107.kt @@ -0,0 +1,17 @@ +fun foo(): String { + val s = try { + "OK" + } catch (e: Exception) { + try { + "" + } catch (ee: Exception) { + "" + } + } + + return s +} + +fun box(): String { + return foo() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt3421.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt3421.kt new file mode 100644 index 00000000000..a3f0590d621 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt3421.kt @@ -0,0 +1,9 @@ +public object Globals{ + operator fun get(key: String, remove: Boolean = true): String { + return "OK" + } +} + +fun box(): String { + return Globals["test"] +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt344.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt344.kt new file mode 100644 index 00000000000..196a5f38daf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt344.kt @@ -0,0 +1,200 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun s0() : Boolean { + val y = "222" + val foo = { + val bar = { y } + bar () + } + return foo() == "222" +} + +fun s1() : Boolean { + var x = "222" + val foo = { + val bar = { + x = "aaa" + } + bar () + } + foo() + return x == "aaa" +} + +fun t1() : Boolean { + var x = "111" + + val y = x + "22" + val foo = { + x = x + "45" + y + x = x.substring(3) + x += "aaa" + Unit + } + foo() + + x += "bbb" + System.out?.println(x) + return x == "4511122aaabbb" +} + +fun t2() : Boolean { + var x = 111 + val y = x + 22 + val foo = { + x = x + 5 + y + x += 5 + x++ + Unit + } + foo() + x -= 55 + System.out?.println(x) + return x == 200 +} + +fun t3() : Boolean { + var x = true + val foo = { + x = false + Unit + } + foo() + return !x +} + +fun t4() : Boolean { + var x = 100.toFloat() + val y = x + 22 + val foo = { + x = x + 200.toFloat() + y + x += 18 + Unit + } + foo() + System.out?.println(x) + return x == 440.toFloat() +} + +fun t5() : Boolean { + var x = 100.toDouble() + val y = x + 22 + val foo = { + x = x + 200.toDouble() + y + x -= 22 + Unit + } + foo() + System.out?.println(x) + return x == 400.toDouble() +} + +fun t6() : Boolean { + var x = 20.toByte() + val y = x + 22 + val foo = { + x = (x + 20.toByte() + y).toByte() + x = (x + 2).toByte() + x-- + Unit + } + foo() + System.out?.println(x) + return x == 83.toByte() +} + +fun t7() : Boolean { + var x : Char = 'a' + val foo = { + x = 'b' + Unit + } + foo() + System.out?.println(x) + return x == 'b' +} + +fun t8() : Boolean { + var x = 20.toShort() + val foo = { + val bar = { + x = 30.toShort() + Unit + } + bar() + Unit + } + foo() + return x == 30.toShort() +} + +fun t9(x0: Int) : Boolean { + var x = x0 + while(x < 100) { + x++ + } + return x == 100 +} + +fun t10() : Boolean { + var y = 1 + val foo = { + val bar = { + y = y + 1 + } + bar() + } + foo() + return y == 2 +} + +fun t11(x0: Int) : Int { + var x = x0 + val foo = { + x = x + 1 + val bar = { + x = x + 1 + x += 3 + } + bar() + } + while(x < 100) { + foo() + } + return x +} + +fun t12(x: Int) : Int { + var y = x + val runnable = object : Runnable { + override fun run () { + y = y + 1 + } + } + while(y < 100) { + runnable.run() + } + return y +} + +fun box(): String { + if (!s0()) return "s0 fail" + if (!s1()) return "s1 fail" + if (!t1()) return "t1 fail" + if (!t2()) return "t2 fail" + if (!t3()) return "t3 fail" + if (!t4()) return "t4 fail" + if (!t5()) return "t5 fail" + if (!t6()) return "t6 fail" + if (!t7()) return "t7 fail" + if (!t8()) return "t8 fail" + if (!t9(0)) return "t9 fail" + if (!t10()) return "t10 fail" + if (t11(1) != 101) return "t11 fail" + if (t12(0) != 100) return "t12 fail" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt3442.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt3442.kt new file mode 100644 index 00000000000..0a28219ff5f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt3442.kt @@ -0,0 +1,8 @@ +// WITH_RUNTIME + +fun box(): String { + val m = hashMapOf() + m.put("b", null) + val oldValue = m.getOrPut("b", { "Foo" }) + return if (oldValue == "Foo") "OK" else "fail: $oldValue" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt3587.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt3587.kt new file mode 100644 index 00000000000..3e1d47b1cd9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt3587.kt @@ -0,0 +1,10 @@ +open class Variable { + val lightVar: LightVariable = if (this is LightVariable) this else LightVariable() +} + +class LightVariable() : Variable() + +fun box(): String { + Variable() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt3850.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt3850.kt new file mode 100644 index 00000000000..03acfce7df7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt3850.kt @@ -0,0 +1,7 @@ +private class One { + val a1 = arrayOf( + object { val fy = "text"} + ) +} + +fun box() = if (One().a1[0].fy == "text") "OK" else "fail" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt3903.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt3903.kt new file mode 100644 index 00000000000..1d08051cded --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt3903.kt @@ -0,0 +1,11 @@ +class Foo { + fun bar(): String { + fun foo(t:() -> T) : T = t() + foo { } + return "OK" + } +} + +fun box(): String { + return Foo().bar() +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt4142.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt4142.kt new file mode 100644 index 00000000000..d7fe122fda7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt4142.kt @@ -0,0 +1,16 @@ +open class B { + val name: String + get() = "OK" +} + +interface A { + val name: String +} + +class C : B(), A { + +} + +fun box(): String { + return C().name +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt4259.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt4259.kt new file mode 100644 index 00000000000..2f5ff42b84a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt4259.kt @@ -0,0 +1,11 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String { + val s: String? = "a" + val o: Char? = s?.get(0) + val c: Any? = o?.javaClass + return if (c != null) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt4262.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt4262.kt new file mode 100644 index 00000000000..d170254879f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt4262.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun > Byte.toEnum(clazz : Class) : E = + (clazz.getMethod("values").invoke(null) as Array)[this.toInt()] + +enum class Letters { A, B, C } + +fun box(): String { + val clazz = Letters::class.java + val r = 1.toByte().toEnum(clazz) + return if (r == Letters.B) "OK" else "Fail: $r" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt4281.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt4281.kt new file mode 100644 index 00000000000..a1e84ddff49 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt4281.kt @@ -0,0 +1,16 @@ +abstract class C { + fun test(x: Int) { + if (x == 0) return + if (this is D) { + val d: D = this + d.test(x - 1) + } + } +} + +class D: C() + +fun box(): String { + D().test(10) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt5056.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt5056.kt new file mode 100644 index 00000000000..eb6855473ee --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt5056.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME + +fun box(): String { + val list = arrayOf("a", "c", "b").sorted() + return if (list.toString() == "[a, b, c]") "OK" else "Fail: $list" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt528.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt528.kt new file mode 100644 index 00000000000..cf19709bf50 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt528.kt @@ -0,0 +1,132 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +package mask + +import java.io.* +import java.util.* + +fun box() : String { + val input = StringReader("/aaa/bbb/ccc/ddd") + + val luhny = Luhny() + input.forEachChar { + luhny.charIn(it) + } + luhny.printAll() + return "OK" +} + +class Luhny() { + val buffer = LinkedList() + val digits = LinkedList() + + var toBeMasked = 0 + + fun charIn(it : Char) { + buffer.addLast(it) + + // Commented for KT-621 + // when (it) { + // .isDigit() => digits.addLast(it.toInt() - '0'.toInt()) + // ' ', '-' => {} + // else => { + // printAll() + // digits.clear() + // } + // } + + if (it.isDigit()) { + digits.addLast(it - '0') + } else if (it == ' ' || it == '-') { + } else { + printAll() + digits.clear() + } + + if (digits.size > 16) + printOneDigit() + check() + } + + fun check() { + if (digits.size < 14) return + print("check") + val sum = digits.sum { i, d -> +// println("$i -> $d") + if (i % 2 == digits.size) { + val f = d * 2 / 10 + val s = d * 2 % 10 +// println("$d: f = $f, s = $s") + (f + s).pr { +// println("to be doubled: $i -> $d : $it") + } + } else d + } +// println(sum) + if (sum % 10 == 0) {print("s"); toBeMasked = digits.size} + } + + fun printOneDigit() { + while (!buffer.isEmpty()) { + val c = buffer.removeFirst() + out(c) + if (c.isDigit()) { + digits.removeFirst() + return + } + } + } + + fun printAll() { + while (!buffer.isEmpty()) + out(buffer.removeFirst()) + } + + fun out(c : Char) { + if (toBeMasked > 0) { + print('X') + toBeMasked-- + } + else { + // print(c) + } + } +} + +fun T.pr(f : (T) -> Unit) : T { + f(this) + return this +} + +fun LinkedList.sum(f : (Int, Int )-> Int): Int { + var sum = 0 + for (i in 1..size) { + val j = size - i + sum += f(j, get(j)) + } + return sum +} + +//fun List.backwards() : Itl = object : Itl { +// override fun iterator() : It = +// object : It { +// var current = size() +// override fun next() : T = get(--current) +// override fun hasNext() : Boolean = current > 0 +// override fun remove() {throw UnsupportedOperationException()} +// } +//} + +// fun Char.isDigit() = Character.isDigit(this) + +fun Reader.forEachChar(body : (Char) -> Unit) { + do { + var i = read(); + if (i == -1) break + body(i.toChar()) + } while(true) +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt529.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt529.kt new file mode 100644 index 00000000000..ca20d00ea2a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt529.kt @@ -0,0 +1,113 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +package mask + +import java.io.* +import java.util.* + +fun box() : String { + val input = StringReader("/aaa/bbb/ccc/ddd") + + val luhny = Luhny() + input.forEachChar { + luhny.process(it) + } + luhny.printAll() + return "OK" +} + +class Luhny() { + private val buffer = ArrayDeque() + private val digits = ArrayDeque(16) + + private var toBeMasked = 0 + + fun process(it : Char) { + buffer.addLast(it) + + // Commented for KT-621 + // when (it) { + // .isDigit() => digits.addLast(it.toInt() - '0'.toInt()) + // ' ', '-' => {} + // else => printAll() + // } + + if (it.isDigit()) { + digits.addLast(it - '0') + } else if (it == ' ' || it == '-') { + } else { + printAll() + } + + if (digits.size > 16) + printOneDigit() + check() + } + + private fun check() { + val size = digits.size + if (size < 14) return + val sum = digits.sum {i, d -> + if (i % 2 == size % 2) double(d) else d + } +// var sum = 0 +// var i = 0 +// for (d in digits) { +// sum += if (i % 2 == size % 2) double(d) else d +// i++ +// } + if (sum % 10 == 0) toBeMasked = digits.size + } + + private fun double(d : Int) = d * 2 / 10 + d * 2 % 10 + + private fun printOneDigit() { + while (!buffer.isEmpty()) { + val c = buffer.removeFirst()!! + print(c) + if (c.isDigit()) { + digits.removeFirst() + return + } + } + } + + fun printAll() { + while (!buffer.isEmpty()) + print(buffer.removeFirst()) + digits.clear() + } + + private fun print(c : Char) { + if (c.isDigit() && toBeMasked > 0) { + kotlin.io.print('X') + toBeMasked-- + } else { + // kotlin.io.print(c) + } + } +} + +// fun Char.isDigit() = Character.isDigit(this) + +fun Iterable.sum(f : (index : Int, value : Int) -> Int) : Int { + var sum = 0 + var i = 0 + for (d in this) { + sum += f(i, d) + i++ + } + return sum +} + +fun Reader.forEachChar(body : (Char) -> Unit) { + do { + var i = read(); + if (i == -1) break + body(i.toChar()) + } while(true) +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt533.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt533.kt new file mode 100644 index 00000000000..8a728eae40b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt533.kt @@ -0,0 +1,150 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +package mask + +import java.io.* +import java.util.* + +fun box() : String { + val input = StringReader("/aaa/bbb/ccc/ddd") + + val luhny = Luhny() + input.forEachChar { + luhny.charIn(it) + } + luhny.printAll() + return "OK" + +} + +class Luhny() { + val buffer = LinkedList() + val digits = LinkedList() + + var toBeMasked = 0 + + fun charIn(it : Char) { + buffer.push(it) + + // Commented for KT-621 + // when (it) { + // .isDigit() => digits.push(it.toInt() - '0'.toInt()) + // ' ', '-' => {} + // else => { + // printAll() + // digits.clear() + // } + // } + + if (it.isDigit()) { + digits.push(it - '0') + } else if (it == ' ' || it == '-') { + } else { + printAll() + digits.clear() + } + + if (digits.size > 16) + printOneDigit() + check() + } + + fun check() { + if (digits.size < 14) return + val sum = digits.sum { i, d -> + if (i % 2 != 0) + d * 2 / 10 + d * 2 % 10 + else d + } + if (sum % 10 == 0) toBeMasked = digits.size + } + + fun printOneDigit() { + while (!buffer.isEmpty()) { + val c = buffer.pop() + out(c) + if (c.isDigit()) { + digits.pop() + return + } + } + } + + fun printAll() { + while (!buffer.isEmpty()) + out(buffer.pop()) + } + + fun out(c : Char) { + if (toBeMasked > 0) { + print('X') + toBeMasked-- + } + else { + // print(c) + } + } +} + +fun LinkedList.sum(f : (Int, Int) -> Int) : Int { + var sum = 0 + var i = 0 + for (d in backwards()) { + sum += f(i, d) + i++ + } + return sum +} + +fun List.backwards() : Iterable = object : Iterable { + override fun iterator() : Iterator = + object : Iterator { + var current = size + override fun next() : T = get(--current) + override fun hasNext() : Boolean = current > 0 + } +} + +// fun Char.isDigit() = Character.isDigit(this) + +//class Queue(initialBufSize : Int) { +// +// private var bufSize = initialBufSize +// private val buf = Array(initialBufSize) +// private var head = 0 +// private var tail = 0 +// private var size = 0 +// +// val empty : Boolean get() = size == 0 +// +// private fun prev(i : Int) = (bufSize + i - 1) % bufSize +// private fun next(i : Int) = (i + 1) % bufSize +// +// fun push(c : T) { +// buf[tail] = c +// tail = prev(tail) +// size++ +// } +// +// fun pop() : T { +// if (size == 0) throw IllegalStateException() +// size-- +// val result = buf[head] +// head = prev(head) +// return result +// } +// +// fun clear() {} +//} + +fun Reader.forEachChar(body : (Char) -> Unit) { + do { + var i = read(); + if (i == -1) break + body(i.toChar()) + } while(true) +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt5395.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt5395.kt new file mode 100644 index 00000000000..11bb02ddf09 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt5395.kt @@ -0,0 +1,13 @@ +class D { + companion object { + protected val F: String = "OK" + } + + inner class E { + fun foo() = F + } +} + +fun box(): String { + return D().E().foo() +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt5445.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt5445.kt new file mode 100644 index 00000000000..808a90f35e6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt5445.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: 1.kt + +package test2 + +import test.A + +public fun box(): String { + return B().test(B()) +} + +public class B : A() { + public fun test(other:Any): String { + if (other is B && other.s == 2) { + return "OK" + } + return "fail" + } +} + +// FILE: 2.kt + +package test + +open class A { + @JvmField protected val s = 2; +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt5445_2.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt5445_2.kt new file mode 100644 index 00000000000..97b4274cab5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt5445_2.kt @@ -0,0 +1,27 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: 1.kt + +package test2 + +import test.A + +class C : A() { + fun a(): String { + return this.s + } +} + +public fun box(): String { + return C().a() +} + +// FILE: 2.kt + +package test + +open class A { + @JvmField protected val s = "OK"; +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt5786_privateWithDefault.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt5786_privateWithDefault.kt new file mode 100644 index 00000000000..916ed482c60 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt5786_privateWithDefault.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME + +fun box(): String { + run { + test("ok") + test("ok", 200) + } + test("ok") + test("ok", 300) + + return "OK" +} + +private fun test(arg1: String, default: Int = 0) = Unit diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt5953.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt5953.kt new file mode 100644 index 00000000000..3a7cdb1f7e5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt5953.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME + +fun box(): String { + val res = (1..3).map { it -> + if (it == 1) + 2 + }; + + var result = "" + for (i in res) + result += " " + return if (result == " ") "OK" else result +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt6153.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt6153.kt new file mode 100644 index 00000000000..cc21778d197 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt6153.kt @@ -0,0 +1,15 @@ +// KT-6153 java.lang.IllegalStateException while building +object Bug { + fun title(id:Int) = when (id) { + 0 -> "OK" + else -> throw Exception("unsupported $id") + } + + private fun T.header(id: Int) = StringBuilder().append(title(id)) + + fun run() = header(0) +} + +fun box(): String { + return Bug.run().toString() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt6434.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt6434.kt new file mode 100644 index 00000000000..49036644c7a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt6434.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +enum class E { + VALUE, + VALUE2 +} + +class C(val nums: Map) { + val normalizedNums = loadNormalizedNums() + + private fun loadNormalizedNums(): Map { + val vals = nums.values + val min = vals.min()!! + val max = vals.max()!! + val rangeDiff = (max - min).toFloat() + val normalizedNums = nums.map { kvp -> + val (e, num) = kvp + //val e = kvp.key + //val num = kvp.value + val normalized = (num - min) / rangeDiff + Pair(e, normalized) + }.toMap() + return normalizedNums + } +} + +fun box(): String { + val res = C(hashMapOf(E.VALUE to 11, E.VALUE2 to 12)).normalizedNums.values.sorted().joinToString() + return if ("0.0, 1.0" == res) "OK" else "fail $res" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt6434_2.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt6434_2.kt new file mode 100644 index 00000000000..19cd842906a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt6434_2.kt @@ -0,0 +1,9 @@ +// WITH_RUNTIME + +fun box(): String { + val p = 1 to 1 + val (e, num) = p + val a = 1f + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt6485.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt6485.kt new file mode 100644 index 00000000000..01977c6cf72 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt6485.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +import kotlin.test.assertEquals +import java.lang.reflect.ParameterizedType +import java.lang.reflect.Type + +open class TypeLiteral { + val type: Type + get() = (javaClass.getGenericSuperclass() as ParameterizedType).getActualTypeArguments()[0] +} + +inline fun typeLiteral(): TypeLiteral = object : TypeLiteral() {} + +fun box(): String { + assertEquals("class java.lang.String", typeLiteral().type.toString()) + assertEquals("java.util.List", typeLiteral>().type.toString()) + assertEquals("java.lang.String[]", typeLiteral>().type.toString()) + assertEquals("java.lang.Integer[]", typeLiteral>().type.toString()) + assertEquals("java.lang.String[][]", typeLiteral>>().type.toString()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt715.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt715.kt new file mode 100644 index 00000000000..63e80a20157 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt715.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.* + +@Suppress("REIFIED_TYPE_PARAMETER_NO_INLINE") +inline fun javaClass(): Class = T::class.java + +val test = "lala".javaClass + +val test2 = javaClass> () + +fun box(): String { + if(test.getCanonicalName() != "java.lang.String") return "fail" + if(test2.getCanonicalName() != "java.util.Iterator") return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt7401.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt7401.kt new file mode 100644 index 00000000000..16294c5031b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt7401.kt @@ -0,0 +1,10 @@ +fun foo(): Long { + var n = 2L + if (n > 0L) { + n++ + } + n++ + return n +} + +fun box() = if (foo() == 4L) "OK" else "Fail" diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt789.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt789.kt new file mode 100644 index 00000000000..9849559160b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt789.kt @@ -0,0 +1,8 @@ +package foo + +fun box() : String { + val a = ArrayList(); + a.add(1) + a.add(2) + return if((a.size == 2) && (a.get(1) == 2) && (a.get(0) == 1)) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt864.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt864.kt new file mode 100644 index 00000000000..df346f2cc36 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt864.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +import java.io.* +import java.util.* + +fun sample() : Reader { + return StringReader("""Hello +World"""); + } + + fun box() : String { + // NOTE: Also tested in stdlib: LineIteratorTest.useLines + + // TODO compiler error + // both these expressions causes java.lang.NoClassDefFoundError: collections/CollectionPackage + val list1 = sample().useLines { it.toList() } + val list2 = sample().useLines>{ it.toCollection(arrayListOf()) } + + if(arrayListOf("Hello", "World") != list1) return "fail" + if(arrayListOf("Hello", "World") != list2) return "fail" + return "OK" + } diff --git a/backend.native/tests/external/codegen/blackbox/regressions/kt998.kt b/backend.native/tests/external/codegen/blackbox/regressions/kt998.kt new file mode 100644 index 00000000000..7fef173ff74 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/kt998.kt @@ -0,0 +1,36 @@ +// WITH_RUNTIME + +fun findPairless(a : IntArray) : Int { + loop@ for (i in a.indices) { + for (j in a.indices) { + if (i != j && a[i] == a[j]) continue@loop + } + return a[i] + } + return -1 +} + +fun hasDuplicates(a : IntArray) : Boolean { + var duplicate = false + loop@ for (i in a.indices) { + for (j in a.indices) { + if (i != j && a[i] == a[j]) { + duplicate = true + break@loop + } + } + } + return duplicate +} + +fun box() : String { + val a = IntArray(5) + a[0] = 0 + a[1] = 0 + a[2] = 1 + a[3] = 1 + a[4] = 5 + if(findPairless(a) != 5) return "fail" + return if(hasDuplicates(a)) "OK" else "fail" + +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/nestedIntersection.kt b/backend.native/tests/external/codegen/blackbox/regressions/nestedIntersection.kt new file mode 100644 index 00000000000..fa19aa885e7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/nestedIntersection.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +interface In +open class A : In +open class B : In + +inline fun select(x: T, y: T) = T::class.java.simpleName + +// This test checks mostly that no StackOverflow happens while mapping type argument of select-call (In) +// See KT-10972 +fun foo(): String = select(A(), B()) + +fun box(): String { + if (foo() != "In") return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/objectCaptureOuterConstructorProperty.kt b/backend.native/tests/external/codegen/blackbox/regressions/objectCaptureOuterConstructorProperty.kt new file mode 100644 index 00000000000..b9011debfe9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/objectCaptureOuterConstructorProperty.kt @@ -0,0 +1,29 @@ +// WITH_RUNTIME + +interface Stream { + fun iterator(): Iterator +} + +class ZippingStream(val stream1: Stream, val stream2: Stream) : Stream> { + override fun iterator(): Iterator> = object : AbstractIterator>() { + val iterator1 = stream1.iterator() + val iterator2 = stream2.iterator() + override fun computeNext() { + if (iterator1.hasNext() && iterator2.hasNext()) { + setNext(iterator1.next() to iterator2.next()) + } else { + done() + } + } + } +} + + +object EmptyStream : Stream { + override fun iterator() = listOf().iterator() +} + +fun box(): String { + ZippingStream(EmptyStream, EmptyStream).iterator().hasNext() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/referenceToSelfInLocal.kt b/backend.native/tests/external/codegen/blackbox/regressions/referenceToSelfInLocal.kt new file mode 100644 index 00000000000..bdda90a6e92 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/referenceToSelfInLocal.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// KT-4351 Cannot resolve reference to self in init of class local to function + +fun box(): String { + var accessedFromConstructor: Class<*>? = null + + class MyClass() { + init { + accessedFromConstructor = MyClass::class.java + } + } + + MyClass() + if (accessedFromConstructor!!.getName().endsWith("MyClass")) { + return "OK" + } else { + return accessedFromConstructor.toString() + } +} diff --git a/backend.native/tests/external/codegen/blackbox/regressions/typeCastException.kt b/backend.native/tests/external/codegen/blackbox/regressions/typeCastException.kt new file mode 100644 index 00000000000..669cfc04943 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/regressions/typeCastException.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import java.util.ArrayList + +// KT-2823 TypeCastException has no message +// KT-5121 Better error message in on casting null to non-null type + +fun box(): String { + try { + val a: Any? = null + a as Array + } + catch (e: TypeCastException) { + if (e.message != "null cannot be cast to non-null type kotlin.Array") { + return "Fail 1: $e" + } + } + + try { + val x: String? = null + x as String + } + catch (e: TypeCastException) { + if (e.message != "null cannot be cast to non-null type kotlin.String") { + return "Fail 2: $e" + } + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/DIExample.kt b/backend.native/tests/external/codegen/blackbox/reified/DIExample.kt new file mode 100644 index 00000000000..9ec149f89f2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/DIExample.kt @@ -0,0 +1,29 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals +import kotlin.reflect.KProperty + +class Project { + fun getInstance(cls: Class): T = + when (cls.getName()) { + "java.lang.Integer" -> 1 as T + "java.lang.String" -> "OK" as T + else -> null!! + } +} + +inline operator fun Project.getValue(t: Any?, p: KProperty<*>): T = getInstance(T::class.java) + +val project = Project() +val x1: Int by project +val x2: String by project + +fun box(): String { + assertEquals(1, x1) + assertEquals("OK", x2) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/anonymousObject.kt b/backend.native/tests/external/codegen/blackbox/reified/anonymousObject.kt new file mode 100644 index 00000000000..2517f1cc929 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/anonymousObject.kt @@ -0,0 +1,24 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +abstract class A { + abstract fun f(): String +} + +inline fun foo(): A { + return object : A() { + override fun f(): String { + return T::class.java.getName() + } + } +} + +fun box(): String { + val y = foo(); + assertEquals("java.lang.String", y.f()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/anonymousObjectNoPropagate.kt b/backend.native/tests/external/codegen/blackbox/reified/anonymousObjectNoPropagate.kt new file mode 100644 index 00000000000..24ef70e04eb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/anonymousObjectNoPropagate.kt @@ -0,0 +1,41 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +interface A { + fun f1(): String + fun f2(): String + fun f3(): String +} + +fun doWork(block: () -> String) = block() +inline fun doWorkInline(block: () -> String) = block() + +fun box(): String { + val x = object { + inline fun bar1(): A = object : A { + override fun f1(): String = T::class.java.getName() + override fun f2(): String = doWork { T::class.java.getName() } + override fun f3(): String = doWorkInline { T::class.java.getName() } + } + + inline fun bar2() = T::class.java.getName() + inline fun bar3() = doWork { T::class.java.getName() } + inline fun bar4() = doWorkInline { T::class.java.getName() } + } + + val y: A = x.bar1() + assertEquals("java.lang.String", y.f1()) + assertEquals("java.lang.String", y.f2()) + assertEquals("java.lang.String", y.f3()) + + + assertEquals("java.lang.Integer", x.bar2()) + assertEquals("java.lang.Double", x.bar3()) + assertEquals("java.lang.Long", x.bar4()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/anonymousObjectReifiedSupertype.kt b/backend.native/tests/external/codegen/blackbox/reified/anonymousObjectReifiedSupertype.kt new file mode 100644 index 00000000000..8c173baea8c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/anonymousObjectReifiedSupertype.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +abstract class A { + abstract fun f(): String +} + +inline fun foo(): A { + return object : A() { + override fun f(): String { + return "OK" + } + } +} + +fun box(): String { + val y = foo(); + assertEquals("OK", y.f()) + assertEquals("A", y.javaClass.getGenericSuperclass()?.toString()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/approximateCapturedTypes.kt b/backend.native/tests/external/codegen/blackbox/reified/approximateCapturedTypes.kt new file mode 100644 index 00000000000..a270f4f0d7e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/approximateCapturedTypes.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// Basically this test checks that no captured type used as argument for signature mapping +class SwOperator: Operator, T> + +interface Operator + +open class Inv + +class Obs { + inline fun lift(lift: Operator) = object : Inv() {} +} + +fun box(): String { + val o: Obs = Obs() + + val inv = o.lift(SwOperator()) + val signature = inv.javaClass.genericSuperclass.toString() + + if (signature != "Inv>") return "fail 1: $signature" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/arraysReification/instanceOf.kt b/backend.native/tests/external/codegen/blackbox/reified/arraysReification/instanceOf.kt new file mode 100644 index 00000000000..eb8f592b691 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/arraysReification/instanceOf.kt @@ -0,0 +1,27 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +inline fun foo(x: Any?) = Pair(x is T, x is T?) + +fun box(): String { + val x1 = foo>(arrayOf("")) + if (x1.toString() != "(true, true)") return "fail 1" + + val x2 = foo?>(arrayOf("")) + if (x2.toString() != "(true, true)") return "fail 2" + + val x3 = foo>(null) + if (x3.toString() != "(false, true)") return "fail 3" + + val x4 = foo?>(null) + if (x4.toString() != "(true, true)") return "fail 4" + + val x5 = foo?>(arrayOf("")) + if (x5.toString() != "(false, false)") return "fail 5" + + val x6 = foo?>(null) + if (x6.toString() != "(true, true)") return "fail 6" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/arraysReification/instanceOfArrays.kt b/backend.native/tests/external/codegen/blackbox/reified/arraysReification/instanceOfArrays.kt new file mode 100644 index 00000000000..1ea7f096e4b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/arraysReification/instanceOfArrays.kt @@ -0,0 +1,40 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +inline fun foo(x: Any?) = Pair(x is T, x is T?) +inline fun bar(y: Any?) = foo>(y) +inline fun barNullable(y: Any?) = foo?>(y) + +fun box(): String { + val x1 = bar(arrayOf("")) + if (x1.toString() != "(true, true)") return "fail 1" + + val x3 = bar(null) + if (x3.toString() != "(false, true)") return "fail 3" + + val x4 = bar(null) + if (x4.toString() != "(false, true)") return "fail 4" + + val x5 = bar(arrayOf("")) + if (x5.toString() != "(false, false)") return "fail 5" + + val x6 = bar(null) + if (x6.toString() != "(false, true)") return "fail 6" + + // barNullable + + val x7 = barNullable(arrayOf("")) + if (x7.toString() != "(true, true)") return "fail 7" + + val x9 = barNullable(null) + if (x9.toString() != "(true, true)") return "fail 9" + + val x10 = barNullable(arrayOf("")) + if (x10.toString() != "(false, false)") return "fail 11" + + val x12 = barNullable(null) + if (x12.toString() != "(true, true)") return "fail 12" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/arraysReification/jClass.kt b/backend.native/tests/external/codegen/blackbox/reified/arraysReification/jClass.kt new file mode 100644 index 00000000000..08514a0359d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/arraysReification/jClass.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +inline fun jClass() = T::class.java +inline fun jClassArray() = jClass>() + +fun box(): String { + if (jClass>().simpleName != "String[]") return "fail 1" + if (jClass().simpleName != "int[]") return "fail 2" + + if (jClassArray().simpleName != "String[]") return "fail 3" + if (jClassArray>().simpleName != "String[][]") return "fail 4" + if (jClassArray().simpleName != "int[][]") return "fail 5" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/arraysReification/jaggedArray.kt b/backend.native/tests/external/codegen/blackbox/reified/arraysReification/jaggedArray.kt new file mode 100644 index 00000000000..1a2bee24db9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/arraysReification/jaggedArray.kt @@ -0,0 +1,15 @@ +inline fun jaggedArray(x: (Int, Int) -> T): Array> = Array(1) { i -> + Array(1) { j -> x(i, j) } +} + +fun box(): String { + val x1: Array> = jaggedArray() { x, y -> "$x-$y" } + if (x1[0][0] != "0-0") return "fail 1" + + val x2: Array>> = jaggedArray() { x, y -> arrayOf("$x-$y") } + if (x2[0][0][0] != "0-0") return "fail 2" + + val x3: Array> = jaggedArray() { x, y -> intArrayOf(x + y + 1) } + if (x3[0][0][0] != 1) return "fail 3" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/arraysReification/jaggedArrayOfNulls.kt b/backend.native/tests/external/codegen/blackbox/reified/arraysReification/jaggedArrayOfNulls.kt new file mode 100644 index 00000000000..07143130bfe --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/arraysReification/jaggedArrayOfNulls.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +inline fun jaggedArrayOfNulls(): Array?> = arrayOfNulls>(1) + +fun box(): String { + val x1 = jaggedArrayOfNulls().javaClass.simpleName + if (x1 != "String[][]") return "fail1: $x1" + + val x2 = jaggedArrayOfNulls>().javaClass.simpleName + if (x2 != "String[][][]") return "fail2: $x2" + + val x3 = jaggedArrayOfNulls().javaClass.simpleName + if (x3 != "int[][][]") return "fail3: $x3" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/arraysReification/jaggedDeep.kt b/backend.native/tests/external/codegen/blackbox/reified/arraysReification/jaggedDeep.kt new file mode 100644 index 00000000000..aa8f36fc23e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/arraysReification/jaggedDeep.kt @@ -0,0 +1,17 @@ +inline fun jaggedArray(x: (Int, Int, Int) -> T): Array>> = Array(1) { i -> + Array(1) { + j -> Array(1) { k -> x(i, j, k) } + } +} + +fun box(): String { + val x1: Array>> = jaggedArray() { x, y, z -> "$x-$y-$z" } + if (x1[0][0][0] != "0-0-0") return "fail 1" + + val x2: Array>>> = jaggedArray() { x, y, z -> arrayOf("$x-$y-$z") } + if (x2[0][0][0][0] != "0-0-0") return "fail 2" + + val x3: Array>> = jaggedArray() { x, y, z -> intArrayOf(x + y + z + 1) } + if (x3[0][0][0][0] != 1) return "fail 3" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/asOnPlatformType.kt b/backend.native/tests/external/codegen/blackbox/reified/asOnPlatformType.kt new file mode 100644 index 00000000000..1a3964f06a7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/asOnPlatformType.kt @@ -0,0 +1,35 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: JavaClass.java + +public class JavaClass { + + public static String nullString() { + return null; + } + + public static String nonnullString() { + return "OK"; + } + +} + +// FILE: kotlin.kt + +fun box(): String { + val nullStr = JavaClass.nullString() + val nonnullStr = JavaClass.nonnullString() + + if (nullStr.foo() != null) return "fail 1" + if (nonnullStr.foo() != nonnullStr) return "fail 2" + + if (nullStr.fooN() != null) return "fail 3" + if (nonnullStr.fooN() != nonnullStr) return "fail 4" + + return "OK" +} + +inline fun T.foo(): T = this as T + +inline fun T.fooN(): T? = this as T? diff --git a/backend.native/tests/external/codegen/blackbox/reified/checkcast.kt b/backend.native/tests/external/codegen/blackbox/reified/checkcast.kt new file mode 100644 index 00000000000..3b10a4bd5f8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/checkcast.kt @@ -0,0 +1,22 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun checkcast(x: Any?): T { + return x as T +} + +fun box(): String { + val x = checkcast("abc") + assertEquals("abc", x) + val y = checkcast(1) + assertEquals(1, y) + + try { + val z = checkcast("abc") + } catch (e: Exception) { + return "OK" + } + + return "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/copyToArray.kt b/backend.native/tests/external/codegen/blackbox/reified/copyToArray.kt new file mode 100644 index 00000000000..4cbf10bdec5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/copyToArray.kt @@ -0,0 +1,17 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun copy(c: Collection): Array { + return c.toTypedArray() +} + +fun box(): String { + val a: Array = copy(listOf("a", "b", "c")) + assertEquals("abc", a.joinToString("")) + + val b: Array = copy(listOf(1,2,3)) + assertEquals("123", b.map { it.toString() }.joinToString("")) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/defaultJavaClass.kt b/backend.native/tests/external/codegen/blackbox/reified/defaultJavaClass.kt new file mode 100644 index 00000000000..ff05c5b2551 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/defaultJavaClass.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun foo(x: Class = T::class.java): String = x.getName() + +inline fun bar(x: R): String = foo() + +fun box(): String { + assertEquals("java.lang.String", foo()) + assertEquals("java.lang.Integer", foo()) + assertEquals("java.lang.Object", foo()) + + assertEquals("java.lang.String", bar("abc")) + assertEquals("java.lang.Integer", bar(1)) + assertEquals("java.lang.Object", bar(Any())) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/filterIsInstance.kt b/backend.native/tests/external/codegen/blackbox/reified/filterIsInstance.kt new file mode 100644 index 00000000000..489c8b6bcc0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/filterIsInstance.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun Array.filterIsInstance(): List { + return this.filter { it is T }.map { it as T } +} + +fun box(): String { + val src: Array = arrayOf(1,2,3.toDouble(), "abc", "cde") + + assertEquals(arrayListOf(1,2), src.filterIsInstance()) + assertEquals(arrayListOf(3.0), src.filterIsInstance()) + assertEquals(arrayListOf("abc", "cde"), src.filterIsInstance()) + assertEquals(src.toList(), src.filterIsInstance()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/innerAnonymousObject.kt b/backend.native/tests/external/codegen/blackbox/reified/innerAnonymousObject.kt new file mode 100644 index 00000000000..c6c995c85a2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/innerAnonymousObject.kt @@ -0,0 +1,32 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +abstract class A { + abstract fun f(): String + override fun toString() = f() +} + +abstract class G { + abstract fun bar(): Any +} + +inline fun foo(): G { + return object : G() { + override fun bar(): Any { + return object : A() { + override fun f(): String = "OK" + } + } + } +} + +fun box(): String { + val y = foo().bar(); + assertEquals("OK", y.toString()) + assertEquals("A", y.javaClass.getGenericSuperclass()?.toString()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/instanceof.kt b/backend.native/tests/external/codegen/blackbox/reified/instanceof.kt new file mode 100644 index 00000000000..3d56c9f4771 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/instanceof.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +inline fun isinstance(x: Any?): Boolean { + return x is T +} + +fun box(): String { + assert(isinstance("abc")) + assert(isinstance(1)) + assert(!isinstance("abc")) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/isOnPlatformType.kt b/backend.native/tests/external/codegen/blackbox/reified/isOnPlatformType.kt new file mode 100644 index 00000000000..a60989dd637 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/isOnPlatformType.kt @@ -0,0 +1,35 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: JavaClass.java + +public class JavaClass { + + public static String nullString() { + return null; + } + + public static String nonnullString() { + return "OK"; + } + +} + +// FILE: kotlin.kt + +fun box(): String { + val nullStr = JavaClass.nullString() + val nonnullStr = JavaClass.nonnullString() + + if (nullStr.foo() != true) return "fail 1" + if (nonnullStr.foo() != true) return "fail 2" + + if (nullStr.fooN() != true) return "fail 3" + if (nonnullStr.fooN() != true) return "fail 4" + + return "OK" +} + +inline fun T.foo(): Boolean = this is T + +inline fun T.fooN(): Boolean = this is T? diff --git a/backend.native/tests/external/codegen/blackbox/reified/javaClass.kt b/backend.native/tests/external/codegen/blackbox/reified/javaClass.kt new file mode 100644 index 00000000000..2e7559b4e78 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/javaClass.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun javaClassName(): String { + return T::class.java.getName() +} + +fun box(): String { + assertEquals("java.lang.String", javaClassName()) + assertEquals("java.lang.Integer", javaClassName()) + assertEquals("java.lang.Object", javaClassName()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/nestedReified.kt b/backend.native/tests/external/codegen/blackbox/reified/nestedReified.kt new file mode 100644 index 00000000000..6787fb86885 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/nestedReified.kt @@ -0,0 +1,47 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun foo(): Array { + val x = object { + inline fun bar(): Array = arrayOf( + T1::class.java.getName(), T::class.java.getName(), R::class.java.getName() + ) + fun f1() = bar() + fun f2() = bar() + fun f3() = bar() + fun f4() = bar() + } + + val x1 = x.f1() + val x2 = x.f2() + val x3 = x.f3() + val x4 = x.f4() + + return arrayOf( + x1[0], x1[1], x1[2], + x2[0], x2[1], x2[2], + x3[0], x3[1], x3[2], + x4[0], x4[1], x4[2] + ) +} + +fun box(): String { + val result = foo() + + val expected = arrayOf( + "java.lang.Double", "java.lang.Integer", "java.lang.Integer", + "java.lang.Integer", "java.lang.Double", "java.lang.Integer", + "java.lang.Boolean", "java.lang.Double", "java.lang.Integer", + "java.lang.Double", "java.lang.Boolean", "java.lang.Integer" + ) + + for (i in expected.indices) { + assertEquals(expected[i], result[i], "$i-th element") + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/nestedReifiedSignature.kt b/backend.native/tests/external/codegen/blackbox/reified/nestedReifiedSignature.kt new file mode 100644 index 00000000000..ea4fe763e54 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/nestedReifiedSignature.kt @@ -0,0 +1,37 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +open class A + +inline fun foo(): Array> { + val x = object { + inline fun bar(): A<*,*,*> = object : A() {} + fun f1() = bar() + fun f2() = bar() + fun f3() = bar() + fun f4() = bar() + } + + return arrayOf(x.f1(), x.f2(), x.f3(), x.f4()) +} + +fun box(): String { + val result = foo() + + val expected = arrayOf( + Triple("java.lang.Double", "java.lang.Integer", "java.lang.Integer"), + Triple("java.lang.Integer", "java.lang.Double", "java.lang.Integer"), + Triple("java.lang.Boolean", "java.lang.Double", "java.lang.Integer"), + Triple("java.lang.Double", "java.lang.Boolean", "java.lang.Integer") + ).map { "A<${it.first}, ${it.second}, ${it.third}>" } + + for (i in expected.indices) { + assertEquals(expected[i], result[i].javaClass.getGenericSuperclass()?.toString(), "$i-th element") + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/newArrayInt.kt b/backend.native/tests/external/codegen/blackbox/reified/newArrayInt.kt new file mode 100644 index 00000000000..74ea8b366f7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/newArrayInt.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +inline fun createArray(n: Int, crossinline block: () -> T): Array { + return Array(n) { block() } +} + +fun box(): String { + + val x = createArray(5) { 3 } + + assert(x.all { it == 3 }) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/nonInlineableLambdaInReifiedFunction.kt b/backend.native/tests/external/codegen/blackbox/reified/nonInlineableLambdaInReifiedFunction.kt new file mode 100644 index 00000000000..c243cb1206b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/nonInlineableLambdaInReifiedFunction.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun foo(block: () -> String) = block() +inline fun bar1(x: T): String = foo() { + T::class.java.getName() +} +inline fun bar2(x: T, y: String): String = foo() { + T::class.java.getName() + "#" + y +} + +fun box(): String { + + assertEquals("java.lang.Integer", bar1(1)) + assertEquals("java.lang.String#OK", bar2("abc", "OK")) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/recursiveInnerAnonymousObject.kt b/backend.native/tests/external/codegen/blackbox/reified/recursiveInnerAnonymousObject.kt new file mode 100644 index 00000000000..e75f5c80b5e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/recursiveInnerAnonymousObject.kt @@ -0,0 +1,40 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +abstract class A { + abstract fun f(): String + override fun toString() = f() +} + +abstract class G { + abstract fun bar(): Any +} + +inline fun baz(): G { + return object : G() { + override fun bar(): Any { + return object : A() { + override fun f(): String = "OK" + } + } + } +} + +inline fun foo(): Pair { + return Pair(baz(), baz()) +} + +fun box(): String { + val res = foo(); + val x1 = res.first.bar() + val x2 = res.second.bar() + assertEquals("OK", x1.toString()) + assertEquals("OK", x2.toString()) + assertEquals("A", x1.javaClass.getGenericSuperclass()?.toString()) + assertEquals("A", x2.javaClass.getGenericSuperclass()?.toString()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/recursiveNewArray.kt b/backend.native/tests/external/codegen/blackbox/reified/recursiveNewArray.kt new file mode 100644 index 00000000000..7925668cc22 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/recursiveNewArray.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +inline fun createArray(n: Int, crossinline block: () -> T): Array { + return Array(n) { block() } +} + +inline fun recursive( + crossinline block: () -> R +): Array { + return createArray(5) { block() } +} + +fun box(): String { + val x = recursive(){ "abc" } + + assert(x.all { it == "abc" }) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/recursiveNonInlineableLambda.kt b/backend.native/tests/external/codegen/blackbox/reified/recursiveNonInlineableLambda.kt new file mode 100644 index 00000000000..364262bcee2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/recursiveNonInlineableLambda.kt @@ -0,0 +1,27 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun foo(block: () -> String) = block() + +inline fun bar1(): String = foo() { + T::class.java.getName() +} +inline fun bar2(y: String): String = foo() { + T::class.java.getName() + "#" + y +} + +inline fun bar3(y: String) = + Pair(bar1(), bar2(y)) + +fun box(): String { + val x = bar3("OK") + + assertEquals("java.lang.Integer", x.first) + assertEquals("java.lang.String#OK", x.second) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/reifiedChain.kt b/backend.native/tests/external/codegen/blackbox/reified/reifiedChain.kt new file mode 100644 index 00000000000..476197c805c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/reifiedChain.kt @@ -0,0 +1,36 @@ +inline fun Any?.check(): Boolean { + return this is T +} + +inline fun Any?.check2(): Boolean { + return check() +} + + +var log = "" +fun log(a: Any?) { + log += a.toString() + ";" +} + +fun test(a: Any?) { + log(a.check()) + log(a.check()) +} + +fun test2(a: Any?) { + log(a.check2()) + log(a.check2()) +} + +fun box(): String { + test("") + test(null) + test2("") + test2(null) + + if (log != "true;true;false;true;true;true;false;true;") { + return "fail" + } + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/reified/reifiedInlineFunOfObject.kt b/backend.native/tests/external/codegen/blackbox/reified/reifiedInlineFunOfObject.kt new file mode 100644 index 00000000000..75387478a8a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/reifiedInlineFunOfObject.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun foo(block: () -> String) = block() + +interface A { + fun f(): String + fun g(): String +} + +fun box(): String { + val x: A = object : A { + private inline fun localClassName(): String = T::class.java.getName() + override fun f(): String = foo { localClassName() } + override fun g(): String = foo { localClassName() } + } + + assertEquals("java.lang.String", x.f()) + assertEquals("java.lang.Integer", x.g()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/reifiedInlineFunOfObjectWithinReified.kt b/backend.native/tests/external/codegen/blackbox/reified/reifiedInlineFunOfObjectWithinReified.kt new file mode 100644 index 00000000000..e211f6e52b8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/reifiedInlineFunOfObjectWithinReified.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun foo(block: () -> String) = block() + +inline fun className(): String = T::class.java.getName() + +inline fun lambdaShouldBeReified(): String = foo { className() } + +interface A { + fun f(): String + fun g(): String +} +inline fun AFactory(): A = object : A { + override fun f(): String = className() + override fun g(): String = foo { className() } +} + +fun box(): String { + assertEquals("java.lang.String", lambdaShouldBeReified()) + assertEquals("java.lang.Integer", lambdaShouldBeReified()) + + val x: A = AFactory() + + assertEquals("java.lang.String", x.f()) + assertEquals("java.lang.Integer", x.g()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/reifiedInlineIntoNonInlineableLambda.kt b/backend.native/tests/external/codegen/blackbox/reified/reifiedInlineIntoNonInlineableLambda.kt new file mode 100644 index 00000000000..6636a564543 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/reifiedInlineIntoNonInlineableLambda.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun foo(block: () -> String) = block() + +inline fun className(): String = T::class.java.getName() + +interface A { + fun f(): String + fun g(): String +} + +fun box(): String { + val x = foo() { + className() + } + + assertEquals("java.lang.String", x) + + val y: A = object : A { + override fun f(): String = foo { className() } + override fun g(): String = foo { className() } + } + + assertEquals("java.lang.String", y.f()) + assertEquals("java.lang.Integer", y.g()) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/safecast.kt b/backend.native/tests/external/codegen/blackbox/reified/safecast.kt new file mode 100644 index 00000000000..10171dd33fe --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/safecast.kt @@ -0,0 +1,19 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun safecast(x: Any?): T? { + return x as? T +} + +fun box(): String { + val x = safecast("abc") + assertEquals("abc", x) + val y = safecast(1) + assertEquals(1, y) + + val z = safecast("abc") + assertEquals(null, z) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/sameIndexRecursive.kt b/backend.native/tests/external/codegen/blackbox/reified/sameIndexRecursive.kt new file mode 100644 index 00000000000..b5fc6022839 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/sameIndexRecursive.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +inline fun createArray(n: Int, crossinline block: () -> Pair): Pair, Array> { + return Pair(Array(n) { block().first }, Array(n) { block().second }) +} + +inline fun recursive( + crossinline block: () -> R +): Pair, Array> { + return createArray(5) { Pair(block(), block()) } +} + +fun box(): String { + val y = createArray(5) { Pair(1, "test") } + val x = recursive(){ "abc" } + + assert(y.first.all { it == 1 } ) + assert(y.second.all { it == "test" }) + assert(x.first.all { it == "abc" }) + assert(x.second.all { it == "abc" }) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/spreads.kt b/backend.native/tests/external/codegen/blackbox/reified/spreads.kt new file mode 100644 index 00000000000..d0861109cbb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/spreads.kt @@ -0,0 +1,26 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun foo(vararg a: T) = a.size + +inline fun bar(a: Array, block: () -> T): Array { + assertEquals(4, foo(*a, block(), block())) + + return arrayOf(*a, block(), block()) +} + +inline fun empty() = arrayOf() + +fun box(): String { + + var i = 0 + val a: Array = bar(arrayOf("1", "2")) { i++; i.toString() } + assertEquals("1234", a.joinToString("")) + + i = 0 + val b: Array = bar(arrayOf(0, 1)) { i++ } + assertEquals("0123", b.map { it.toString() }.joinToString("")) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/reified/varargs.kt b/backend.native/tests/external/codegen/blackbox/reified/varargs.kt new file mode 100644 index 00000000000..73eaba238dc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/reified/varargs.kt @@ -0,0 +1,28 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun foo(vararg a: T) = a.size + +inline fun bar(block: () -> T): Array { + assertEquals(2, foo(block(), block())) + + return arrayOf(block(), block(), block()) +} + +inline fun empty() = arrayOf() + +fun box(): String { + var i = 0 + val a: Array = bar() { i++; i.toString() } + assertEquals("345", a.joinToString("")) + + i = 0 + val b: Array = bar() { i++ } + assertEquals("234", b.map { it.toString() }.joinToString("")) + + val c: Array = empty() + assertEquals(0, c.size) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/safeCall/genericNull.kt b/backend.native/tests/external/codegen/blackbox/safeCall/genericNull.kt new file mode 100644 index 00000000000..d8ffc413616 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/safeCall/genericNull.kt @@ -0,0 +1,8 @@ +fun foo(t: T) { + t?.toInt() +} + +fun box(): String { + foo(null) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/safeCall/kt1572.kt b/backend.native/tests/external/codegen/blackbox/safeCall/kt1572.kt new file mode 100644 index 00000000000..d3b3c52bde1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/safeCall/kt1572.kt @@ -0,0 +1,23 @@ +//KT-1572 Frontend doesn't mark all vars included in closure as refs. + +class A(val t : Int) {} + +fun testKt1572() : Boolean { + var a = A(0) + var b = A(3) + val changer = {a = b} + b = A(10) // this change has no effect on changer + changer() + return (a.t == 10) +} + +fun testPrimitives() : Boolean { + var a = 0 + var b = 3 + val changer = {a = b} + b = 10 + changer() + return (a == 10) +} + +fun box() = if (testKt1572() && testPrimitives()) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/safeCall/kt232.kt b/backend.native/tests/external/codegen/blackbox/safeCall/kt232.kt new file mode 100644 index 00000000000..f23e75dbce1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/safeCall/kt232.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class A() { + fun foo() { + System.out?.println(1) + } +} + +fun box() : String { + val a : A = A() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/safeCall/kt245.kt b/backend.native/tests/external/codegen/blackbox/safeCall/kt245.kt new file mode 100644 index 00000000000..0678b947098 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/safeCall/kt245.kt @@ -0,0 +1,32 @@ +fun foo() { + val l = ArrayList(2) + l.add(1) + + for (el in l) {} + + //verify error "Expecting to find integer on stack" + val iterator = l.iterator() + + //another verify error "Mismatched stack types" + while (iterator?.hasNext() ?: false) { + val i = iterator?.next() + } + + //the same + if (iterator != null) { + while (iterator.hasNext()) { + val i = iterator?.next() + } + } + + //this way it works + if (iterator != null) { + while (iterator.hasNext()) { + iterator.next() //because of the bug KT-244 i can't write "val i = iterator.next()" + } + } +} + +fun box() : String { + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/safeCall/kt247.kt b/backend.native/tests/external/codegen/blackbox/safeCall/kt247.kt new file mode 100644 index 00000000000..55a7fbe74f8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/safeCall/kt247.kt @@ -0,0 +1,38 @@ +fun t1() : Boolean { + val s1 : String? = "sff" + val s2 : String? = null + return s1?.length == 3 && s2?.length == null +} + +fun t2() : Boolean { + val c1: C? = C(1) + val c2: C? = null + return c1?.x == 1 && c2?.x == null +} + +fun t3() { + val d: D = D("s") + val x = d?.s + if (!(d?.s == "s")) throw AssertionError() +} + +fun t4() { + val e: E? = E() + if (!(e?.bar() == e)) throw AssertionError() + val x = e?.foo() +} + +fun box() : String { + if(!t1 ()) return "fail" + if(!t2 ()) return "fail" + t3() + t4() + return "OK" +} + +class C(val x: Int) +class D(val s: String) +class E() { + fun foo() = 1 + fun bar() = this +} diff --git a/backend.native/tests/external/codegen/blackbox/safeCall/kt3430.kt b/backend.native/tests/external/codegen/blackbox/safeCall/kt3430.kt new file mode 100644 index 00000000000..19620029283 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/safeCall/kt3430.kt @@ -0,0 +1,6 @@ +fun f(b : Int.(Int)->Int) = 1?.b(1) + +fun box(): String { + val x = f { this + it } + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/safeCall/kt4733.kt b/backend.native/tests/external/codegen/blackbox/safeCall/kt4733.kt new file mode 100644 index 00000000000..dde6d4af7cb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/safeCall/kt4733.kt @@ -0,0 +1,27 @@ +class Test { + val Long.foo: Long + get() = this + 1 + + val Int.foo: Int + get() = this + 1 + + fun testLong(): Long? { + var s: Long? = 10; + return s?.foo + } + + fun testInt(): Int? { + var s: Int? = 11; + return s?.foo + } +} + +fun box(): String { + val s = Test() + + if (s.testLong() != 11.toLong()) return "fail 1" + + if (s.testInt() != 12) return "fail 1" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/safeCall/primitive.kt b/backend.native/tests/external/codegen/blackbox/safeCall/primitive.kt new file mode 100644 index 00000000000..64decc4e76b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/safeCall/primitive.kt @@ -0,0 +1,8 @@ +fun Int.foo() = 239 +fun Long.bar() = 239.toLong() + +fun box(): String { + 42?.foo() + 42.toLong()?.bar() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/safeCall/safeCallOnLong.kt b/backend.native/tests/external/codegen/blackbox/safeCall/safeCallOnLong.kt new file mode 100644 index 00000000000..9937adc2991 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/safeCall/safeCallOnLong.kt @@ -0,0 +1,6 @@ +fun f(b : Long.(Long)->Long) = 1L?.b(2L) + +fun box(): String { + val x = f { this + it } + return if (x == 3L) "OK" else "fail $x" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/sam/constructors/comparator.kt b/backend.native/tests/external/codegen/blackbox/sam/constructors/comparator.kt new file mode 100644 index 00000000000..894b52dfe03 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/sam/constructors/comparator.kt @@ -0,0 +1,8 @@ +// WITH_RUNTIME + +fun box(): String { + val list = mutableListOf(3, 2, 4, 8, 1, 5) + val expected = listOf(8, 5, 4, 3, 2, 1) + list.sortWith(Comparator { a, b -> b - a }) + return if (list == expected) "OK" else list.toString() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/sam/constructors/filenameFilter.kt b/backend.native/tests/external/codegen/blackbox/sam/constructors/filenameFilter.kt new file mode 100644 index 00000000000..a6651307bed --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/sam/constructors/filenameFilter.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +import java.io.* + +fun box(): String { + val ACCEPT_NAME = "test" + val WRONG_NAME = "wrong" + + val filter = FileFilter { file -> ACCEPT_NAME == file?.getName() } + + if (!filter.accept(File(ACCEPT_NAME))) return "Wrong answer for $ACCEPT_NAME" + if (filter.accept(File(WRONG_NAME))) return "Wrong answer for $WRONG_NAME" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/sam/constructors/nonLiteralComparator.kt b/backend.native/tests/external/codegen/blackbox/sam/constructors/nonLiteralComparator.kt new file mode 100644 index 00000000000..5dfa3b5926f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/sam/constructors/nonLiteralComparator.kt @@ -0,0 +1,9 @@ +// WITH_RUNTIME + +fun box(): String { + val list = mutableListOf(3, 2, 4, 8, 1, 5) + val expected = listOf(8, 5, 4, 3, 2, 1) + val comparatorFun: (Int, Int) -> Int = { a, b -> b - a } + list.sortWith(Comparator(comparatorFun)) + return if (list == expected) "OK" else list.toString() +} diff --git a/backend.native/tests/external/codegen/blackbox/sam/constructors/nonLiteralFilenameFilter.kt b/backend.native/tests/external/codegen/blackbox/sam/constructors/nonLiteralFilenameFilter.kt new file mode 100644 index 00000000000..d6672316a1c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/sam/constructors/nonLiteralFilenameFilter.kt @@ -0,0 +1,17 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +import java.io.* + +fun box(): String { + val ACCEPT_NAME = "test" + val WRONG_NAME = "wrong" + + val f : (File?) -> Boolean = { file -> ACCEPT_NAME == file?.getName() } + val filter = FileFilter(f) + + if (!filter.accept(File(ACCEPT_NAME))) return "Wrong answer for $ACCEPT_NAME" + if (filter.accept(File(WRONG_NAME))) return "Wrong answer for $WRONG_NAME" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/sam/constructors/nonLiteralRunnable.kt b/backend.native/tests/external/codegen/blackbox/sam/constructors/nonLiteralRunnable.kt new file mode 100644 index 00000000000..59818629db0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/sam/constructors/nonLiteralRunnable.kt @@ -0,0 +1,9 @@ +// TARGET_BACKEND: JVM + +fun box(): String { + var result = "FAIL" + val f = { result = "OK" } + val r = Runnable(f) + r.run() + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/sam/constructors/nonTrivialRunnable.kt b/backend.native/tests/external/codegen/blackbox/sam/constructors/nonTrivialRunnable.kt new file mode 100644 index 00000000000..23dd339127c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/sam/constructors/nonTrivialRunnable.kt @@ -0,0 +1,13 @@ +// TARGET_BACKEND: JVM + +var result = "FAIL" + +fun getFun(): () -> Unit { + return { result = "OK" } +} + +fun box(): String { + val r = Runnable(getFun()) + r.run() + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/sam/constructors/runnable.kt b/backend.native/tests/external/codegen/blackbox/sam/constructors/runnable.kt new file mode 100644 index 00000000000..7c4564f0b50 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/sam/constructors/runnable.kt @@ -0,0 +1,9 @@ +// TARGET_BACKEND: JVM + +var result = "FAIL" + +fun box(): String { + val r = Runnable { result = "OK" } + r.run() + return result +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/sam/constructors/runnableAccessingClosure1.kt b/backend.native/tests/external/codegen/blackbox/sam/constructors/runnableAccessingClosure1.kt new file mode 100644 index 00000000000..1381931b9f1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/sam/constructors/runnableAccessingClosure1.kt @@ -0,0 +1,10 @@ +// TARGET_BACKEND: JVM + +fun box(): String { + val o = "O" + var result = "" + + val r = Runnable { result = o + "K" } //capturing local vals and local var + r.run() + return result +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/sam/constructors/runnableAccessingClosure2.kt b/backend.native/tests/external/codegen/blackbox/sam/constructors/runnableAccessingClosure2.kt new file mode 100644 index 00000000000..15c2ff185e9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/sam/constructors/runnableAccessingClosure2.kt @@ -0,0 +1,13 @@ +// TARGET_BACKEND: JVM + +class Box(val s: String) { + fun extract(): String { + var result = "" + Runnable { result = s }.run() // capturing this and local var + return result + } +} + +fun box(): String { + return Box("OK").extract() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/sam/constructors/samWrappersDifferentFiles.kt b/backend.native/tests/external/codegen/blackbox/sam/constructors/samWrappersDifferentFiles.kt new file mode 100644 index 00000000000..3b1cfbc0298 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/sam/constructors/samWrappersDifferentFiles.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: 1/wrapped.kt + +fun getWrapped1(): Runnable { + val f = { } + return Runnable(f) +} + +// FILE: 2/wrapped2.kt + +fun getWrapped2(): Runnable { + val f = { } + return Runnable(f) +} + +// FILE: box.kt + +fun box(): String { + val class1 = getWrapped1().javaClass + val class2 = getWrapped2().javaClass + + return if (class1 != class2) "OK" else "Same class: $class1" +} diff --git a/backend.native/tests/external/codegen/blackbox/sam/constructors/sameWrapperClass.kt b/backend.native/tests/external/codegen/blackbox/sam/constructors/sameWrapperClass.kt new file mode 100644 index 00000000000..ee39d412a0c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/sam/constructors/sameWrapperClass.kt @@ -0,0 +1,10 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + val f = { } + val class1 = (Runnable(f) as Object).getClass() + val class2 = (Runnable(f) as Object).getClass() + + return if (class1 == class2) "OK" else "$class1 $class2" +} diff --git a/backend.native/tests/external/codegen/blackbox/sam/constructors/syntheticVsReal.kt b/backend.native/tests/external/codegen/blackbox/sam/constructors/syntheticVsReal.kt new file mode 100644 index 00000000000..70ad7f5b42b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/sam/constructors/syntheticVsReal.kt @@ -0,0 +1,14 @@ +// TARGET_BACKEND: JVM + +var global = "" + +fun Runnable(f: () -> Unit) = object : Runnable { + public override fun run() { + global = "OK" + } +} + +fun box(): String { + Runnable { global = "FAIL" } .run() + return global +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/sealed/objects.kt b/backend.native/tests/external/codegen/blackbox/sealed/objects.kt new file mode 100644 index 00000000000..c33a71d498f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/sealed/objects.kt @@ -0,0 +1,11 @@ +sealed class Season { + object Warm: Season() + object Cold: Season() +} + +fun foo(): Season = Season.Warm + +fun box() = when(foo()) { + Season.Warm -> "OK" + Season.Cold -> "Fail: Cold, should be Warm" +} diff --git a/backend.native/tests/external/codegen/blackbox/sealed/simple.kt b/backend.native/tests/external/codegen/blackbox/sealed/simple.kt new file mode 100644 index 00000000000..01ae3af2c95 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/sealed/simple.kt @@ -0,0 +1,11 @@ +sealed class Season { + class Warm: Season() + class Cold: Season() +} + +fun foo(): Season = Season.Warm() + +fun box() = when(foo()) { + is Season.Warm -> "OK" + is Season.Cold -> "Fail: Cold, should be Warm" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/accessToCompanion.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/accessToCompanion.kt new file mode 100644 index 00000000000..0c9e1d2df2e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/accessToCompanion.kt @@ -0,0 +1,15 @@ +internal class A(val result: Int) { + companion object { + fun foo(): Int = 1 + val prop = 2 + val C = 3 + } + + constructor() : this(foo() + prop + C) +} + +fun box(): String { + val result = A().result + if (result != 6) return "fail: $result" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/accessToNestedObject.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/accessToNestedObject.kt new file mode 100644 index 00000000000..3093181e4bd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/accessToNestedObject.kt @@ -0,0 +1,16 @@ +class A(val result: Int) { + object B { + fun bar(): Int = 4 + val prop = 5 + } + object C { + } + + constructor() : this(B.bar() + B.prop) +} + +fun box(): String { + val result = A().result + if (result != 9) return "fail: $result" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/basicNoPrimaryManySinks.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/basicNoPrimaryManySinks.kt new file mode 100644 index 00000000000..862ed7e242c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/basicNoPrimaryManySinks.kt @@ -0,0 +1,35 @@ +var sideEffects: String = "" + +class A { + var prop: String = "" + init { + sideEffects += prop + "first" + } + + constructor(x: String) { + prop = x + sideEffects += "#third" + } + + init { + sideEffects += prop + "#second" + } + + constructor(x: Int) { + prop += "$x#int" + sideEffects += "#fourth" + } +} + +fun box(): String { + val a1 = A("abc") + if (a1.prop != "abc") return "fail1: ${a1.prop}" + if (sideEffects != "first#second#third") return "fail1-sideEffects: ${sideEffects}" + + sideEffects = "" + val a2 = A(123) + if (a2.prop != "123#int") return "fail2: ${a2.prop}" + if (sideEffects != "first#second#fourth") return "fail2-sideEffects: ${sideEffects}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/basicNoPrimaryOneSink.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/basicNoPrimaryOneSink.kt new file mode 100644 index 00000000000..23f796276c0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/basicNoPrimaryOneSink.kt @@ -0,0 +1,41 @@ +internal var sideEffects: String = "" + +internal class A { + var prop: String = "" + init { + sideEffects += prop + "first" + } + + constructor() {} + + constructor(x: String): this() { + prop = x + sideEffects += "#third" + } + + init { + sideEffects += prop + "#second" + } + + constructor(x: Int): this(x.toString()) { + prop += "#int" + sideEffects += "#fourth" + } +} + +fun box(): String { + val a1 = A("abc") + if (a1.prop != "abc") return "fail1: ${a1.prop}" + if (sideEffects != "first#second#third") return "fail1-sideEffects: ${sideEffects}" + + sideEffects = "" + val a2 = A(123) + if (a2.prop != "123#int") return "fail2: ${a2.prop}" + if (sideEffects != "first#second#third#fourth") return "fail2-sideEffects: ${sideEffects}" + + sideEffects = "" + val a3 = A() + if (a3.prop != "") return "fail2: ${a3.prop}" + if (sideEffects != "first#second") return "fail3-sideEffects: ${sideEffects}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/basicPrimary.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/basicPrimary.kt new file mode 100644 index 00000000000..6195900e1d8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/basicPrimary.kt @@ -0,0 +1,39 @@ +var sideEffects: String = "" + +class A() { + var prop: String = "" + init { + sideEffects += prop + "first" + } + + constructor(x: String): this() { + prop = x + sideEffects += "#third" + } + + init { + sideEffects += prop + "#second" + } + + constructor(x: Int): this(x.toString()) { + prop += "#int" + sideEffects += "#fourth" + } +} + +fun box(): String { + val a1 = A("abc") + if (a1.prop != "abc") return "fail1: ${a1.prop}" + if (sideEffects != "first#second#third") return "fail1-sideEffects: ${sideEffects}" + + sideEffects = "" + val a2 = A(123) + if (a2.prop != "123#int") return "fail2: ${a2.prop}" + if (sideEffects != "first#second#third#fourth") return "fail2-sideEffects: ${sideEffects}" + + sideEffects = "" + val a3 = A() + if (a3.prop != "") return "fail2: ${a3.prop}" + if (sideEffects != "first#second") return "fail3-sideEffects: ${sideEffects}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/callFromLocalSubClass.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/callFromLocalSubClass.kt new file mode 100644 index 00000000000..e74d65b029d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/callFromLocalSubClass.kt @@ -0,0 +1,15 @@ +fun box(): String { + val z = "K" + open class A(val x: String) { + constructor() : this("O") + + val y: String + get() = z + } + + class B : A() + + val b = B() + + return b.x + b.y +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/callFromPrimaryWithNamedArgs.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/callFromPrimaryWithNamedArgs.kt new file mode 100644 index 00000000000..30fc0208f2c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/callFromPrimaryWithNamedArgs.kt @@ -0,0 +1,11 @@ +open class A(val result: String) { + constructor(x: Int = 11, y: Int = 22, z: Int = 33) : this("$x$y$z") +} + +class B() : A(y = 44) + +fun box(): String { + val result = B().result + if (result != "114433") return "fail: $result" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/callFromPrimaryWithOptionalArgs.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/callFromPrimaryWithOptionalArgs.kt new file mode 100644 index 00000000000..71955e44537 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/callFromPrimaryWithOptionalArgs.kt @@ -0,0 +1,11 @@ +open class A(val result: String) { + constructor(x: Int, y: Int = 99) : this("$x$y") +} + +class B(x: Int) : A(x) + +fun box(): String { + val result = B(11).result + if (result != "1199") return "fail: $result" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/callFromSubClass.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/callFromSubClass.kt new file mode 100644 index 00000000000..7dd165dbc23 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/callFromSubClass.kt @@ -0,0 +1,12 @@ +open class A(val x: String, val z: String) { + constructor(z: String) : this("O", z) +} + +class B(val y: String) : A("_") + +fun box(): String { + val b = B("K") + val result = b.z + b.x + b.y + if (result != "_OK") return "fail: $result" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/clashingDefaultConstructors.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/clashingDefaultConstructors.kt new file mode 100644 index 00000000000..bad07d0d16b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/clashingDefaultConstructors.kt @@ -0,0 +1,35 @@ +open class A(val x: String = "abc", val y: String = "efg") { + constructor(x: String, y: String, z: Int): this(x, y + "#" + z.toString()) + + override fun toString() = "$x#$y" +} + +class B : A { + constructor(x: String, y: String, z: Int): super(x, y + z.toString()) + constructor(x: String = "xyz", y: String = "123") : super(x, y) + constructor(x: Double): super(x.toString()) +} + +fun box(): String { + val a1 = A().toString() + if (a1 != "abc#efg") return "fail1: $a1" + + val a2 = A("hij", "klm", 1).toString() + if (a2 != "hij#klm#1") return "fail2: $a2" + + val a3 = A(x="xyz").toString() + if (a3 != "xyz#efg") return "fail3: $a3" + + val b1 = B().toString() + if (b1 != "xyz#123") return "fail4: $b1" + + val b2 = B("hij", "klm", 2).toString() + if (b2 != "hij#klm2") return "fail5: $b2" + + val b3 = B(123.1).toString() + if (b3 != "123.1#efg") return "fail6: $b3" + + val b4 = B(x="test").toString() + if (b4 != "test#123") return "fail7: $b4" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/dataClasses.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/dataClasses.kt new file mode 100644 index 00000000000..074508611b6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/dataClasses.kt @@ -0,0 +1,53 @@ +internal data class A1(val prop1: String) { + val prop2: String = "const2" + var prop3: String = "" + + constructor(): this("default") { + prop3 = "empty" + } + constructor(x: Int): this(x.toString()) { + prop3 = "int" + } + + fun f(): String = "$prop1#$prop2#$prop3" +} + +internal class A2 private constructor() { + var prop1: String = "" + var prop2: String = "const2" + var prop3: String = "" + + constructor(arg: String): this() { + prop1 = arg + } + constructor(x: Double): this() { + prop1 = "default" + prop3 = "empty" + } + constructor(x: Int): this(x.toString()) { + prop3 = "int" + } + + fun f(): String = "$prop1#$prop2#$prop3" +} + +fun box(): String { + val a1x = A1("asd") + if (a1x.f() != "asd#const2#") return "fail1: ${a1x.f()}" + if (a1x.toString() != "A1(prop1=asd)") return "fail1s: ${a1x.toString()}" + val a1y = A1() + if (a1y.f() != "default#const2#empty") return "fail2: ${a1y.f()}" + if (a1y.toString() != "A1(prop1=default)") return "fail2s: ${a1y.toString()}" + val a1z = A1(5) + if (a1z.f() != "5#const2#int") return "fail3: ${a1z.f()}" + if (a1z.toString() != "A1(prop1=5)") return "fail3s: ${a1z.toString()}" + + val a2x = A2("asd") + if (a2x.f() != "asd#const2#") return "fail4: ${a2x.f()}" + val a2y = A2(123.0) + if (a2y.f() != "default#const2#empty") return "fail5: ${a2y.f()}" + val a2z = A2(5) + if (a2z.f() != "5#const2#int") return "fail6: ${a2z.f()}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/defaultArgs.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/defaultArgs.kt new file mode 100644 index 00000000000..3c9d312462e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/defaultArgs.kt @@ -0,0 +1,34 @@ +val global = "OK" +class A { + val prop: String + constructor(arg1: String = global) { + prop = arg1 + } + constructor(arg1: String = global, arg2: Long) { + prop = "$arg1#$arg2" + } + constructor(arg1: String = global, argDouble: Double, arg3: Long = 1L) { + prop = "$arg1#$argDouble#$arg3" + } +} + +fun box(): String { + val a1 = A() + if (a1.prop != "OK") return "fail1: ${a1.prop}" + val a2 = A("A") + if (a2.prop != "A") return "fail2: ${a2.prop}" + + val a3 = A(arg2=123) + if (a3.prop != "OK#123") return "fail3: ${a3.prop}" + val a4 = A("A", arg2=123) + if (a4.prop != "A#123") return "fail4: ${a4.prop}" + + val a5 = A(argDouble=23.1) + if (a5.prop != "OK#23.1#1") return "fail5: ${a5.prop}" + val a6 = A("A", argDouble=23.1) + if (a6.prop != "A#23.1#1") return "fail6: ${a6.prop}" + val a7 = A("A", arg3=2L, argDouble=23.1) + if (a7.prop != "A#23.1#2") return "fail7: ${a7.prop}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/defaultParametersNotDuplicated.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/defaultParametersNotDuplicated.kt new file mode 100644 index 00000000000..409e42f9ec0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/defaultParametersNotDuplicated.kt @@ -0,0 +1,15 @@ +var global = 0 + +fun sideEffect() = global++ + +class A(val x: String) { + constructor(y: Int = sideEffect(), z: (Int) -> Int = { it + sideEffect() }) : this("$y:${z(y)}") {} +} + +fun box(): String { + var a = A() + if (a.x != "0:1") return "failed1: ${a.x}" + if (global != 2) return "failed2: ${global}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/delegateWithComplexExpression.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/delegateWithComplexExpression.kt new file mode 100644 index 00000000000..999d944d7f1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/delegateWithComplexExpression.kt @@ -0,0 +1,46 @@ +var log = "" + +open class Base(val s: String) + +class A(s: String) : Base(s) { + constructor(i: Int) : this("O" + if (i == 23) { + log += "logged1;" + "K" + } + else { + "fail" + }) + + constructor(i: Long) : this(if (i == 23L) { + log += "logged2;" + 23 + } + else { + 42 + }) +} + +class B : Base { + constructor(i: Int) : super("O" + if (i == 23) { + log += "logged3;" + "K" + } + else { + "fail" + }) +} + +fun box(): String { + var result = A(23).s + if (result != "OK") return "fail1: $result" + + result = A(23L).s + if (result != "OK") return "fail2: $result" + + result = B(23).s + if (result != "OK") return "fail3: $result" + + if (log != "logged1;logged2;logged1;logged3;") return "fail log: $log" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/delegatedThisWithLambda.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/delegatedThisWithLambda.kt new file mode 100644 index 00000000000..b48d1356430 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/delegatedThisWithLambda.kt @@ -0,0 +1,9 @@ +class A(val f: () -> Int) { + constructor() : this({ 23 }) +} + +fun box(): String { + val result = A().f() + if (result != 23) return "fail: $result" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/delegationWithPrimary.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/delegationWithPrimary.kt new file mode 100644 index 00000000000..42690e92b97 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/delegationWithPrimary.kt @@ -0,0 +1,17 @@ +internal interface A { + fun foo(): String +} + +internal class B : A { + override fun foo() = "OK" +} + +internal val global = B() + +internal class C(x: Int) : A by global { + constructor(): this(1) +} + +fun box(): String { + return C().foo() +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/enums.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/enums.kt new file mode 100644 index 00000000000..2d62a075bb9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/enums.kt @@ -0,0 +1,62 @@ +enum class A1(val prop1: String) { + X("asd"), + Y() { + override fun f() = super.f() + "#Y" + }, + Z(5); + + val prop2: String = "const2" + var prop3: String = "" + + constructor(): this("default") { + prop3 = "empty" + } + constructor(x: Int): this(x.toString()) { + prop3 = "int" + } + + open fun f(): String = "$prop1#$prop2#$prop3" +} + +enum class A2 { + X("asd"), + Y() { + override fun f() = super.f() + "#Y" + }, + Z(5); + + val prop1: String + val prop2: String = "const2" + var prop3: String = "" + + constructor(arg: String) { + prop1 = arg + } + constructor() { + prop1 = "default" + prop3 = "empty" + } + constructor(x: Int): this(x.toString()) { + prop3 = "int" + } + + open fun f(): String = "$prop1#$prop2#$prop3" +} + +fun box(): String { + val a1x = A1.X + if (a1x.f() != "asd#const2#") return "fail1: ${a1x.f()}" + val a1y = A1.Y + if (a1y.f() != "default#const2#empty#Y") return "fail2: ${a1y.f()}" + val a1z = A1.Z + if (a1z.f() != "5#const2#int") return "fail3: ${a1z.f()}" + + val a2x = A2.X + if (a2x.f() != "asd#const2#") return "fail4: ${a2x.f()}" + val a2y = A2.Y + if (a2y.f() != "default#const2#empty#Y") return "fail5: ${a2y.f()}" + val a2z = A2.Z + if (a2z.f() != "5#const2#int") return "fail6: ${a2z.f()}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/generics.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/generics.kt new file mode 100644 index 00000000000..a025954f6dd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/generics.kt @@ -0,0 +1,23 @@ +internal open class B(val x: T, val y: T) { + constructor(x: T): this(x, x) + override fun toString() = "$x#$y" +} + +internal class A : B { + constructor(): super("default") + constructor(x: String): super(x, "default") +} + +fun box(): String { + val b1 = B("1", "2").toString() + if (b1 != "1#2") return "fail1: $b1" + val b2 = B("abc").toString() + if (b2 != "abc#abc") return "fail2: $b2" + + val a1 = A().toString() + if (a1 != "default#default") return "fail3: $a1" + val a2 = A("xyz").toString() + if (a2 != "xyz#default") return "fail4: $a2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/innerClasses.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/innerClasses.kt new file mode 100644 index 00000000000..9d0851c426b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/innerClasses.kt @@ -0,0 +1,79 @@ +class Outer { + val outerProp: String + constructor(x: String) { + outerProp = x + } + + var sideEffects = "" + + inner class A1() { + var prop: String = "" + init { + sideEffects += outerProp + "#" + prop + "first" + } + + constructor(x: String): this() { + prop = x + "#${outerProp}" + sideEffects += "#third" + } + + init { + sideEffects += prop + "#second" + } + + constructor(x: Int): this(x.toString() + "#" + outerProp) { + prop += "#int" + sideEffects += "#fourth" + } + } + + inner class A2 { + var prop: String = "" + init { + sideEffects += outerProp + "#" + prop + "first" + } + + constructor(x: String) { + prop = x + "#$outerProp" + sideEffects += "#third" + } + + init { + sideEffects += prop + "#second" + } + + constructor(x: Int) { + prop += "$x#$outerProp#int" + sideEffects += "#fourth" + } + } +} + +fun box(): String { + val outer1 = Outer("propValue1") + val a1 = outer1.A1("abc") + if (a1.prop != "abc#propValue1") return "fail1: ${a1.prop}" + if (outer1.sideEffects != "propValue1#first#second#third") return "fail1-sideEffects: ${outer1.sideEffects}" + + val outer2 = Outer("propValue2") + val a2 = outer2.A1(123) + if (a2.prop != "123#propValue2#propValue2#int") return "fail2: ${a2.prop}" + if (outer2.sideEffects != "propValue2#first#second#third#fourth") return "fail2-sideEffects: ${outer2.sideEffects}" + + val outer3 = Outer("propValue3") + val a3 = outer3.A1() + if (a3.prop != "") return "fail2: ${a3.prop}" + if (outer3.sideEffects != "propValue3#first#second") return "fail3-sideEffects: ${outer3.sideEffects}" + + val outer4 = Outer("propValue4") + val a4 = outer4.A2("abc") + if (a4.prop != "abc#propValue4") return "fail4: ${a4.prop}" + if (outer4.sideEffects != "propValue4#first#second#third") return "fail4-sideEffects: ${outer4.sideEffects}" + + val outer5 = Outer("propValue5") + val a5 = outer5.A2(123) + if (a5.prop != "123#propValue5#int") return "fail5: ${a5.prop}" + if (outer5.sideEffects != "propValue5#first#second#fourth") return "fail5-sideEffects: ${outer5.sideEffects}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/innerClassesInheritance.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/innerClassesInheritance.kt new file mode 100644 index 00000000000..f68b538d5ef --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/innerClassesInheritance.kt @@ -0,0 +1,66 @@ +class Outer { + val outerProp: String + constructor(x: String) { + outerProp = x + } + + var sideEffects = "" + + abstract inner class A1 { + var parentProp: String = "" + init { + sideEffects += outerProp + "#" + parentProp + "first" + } + + protected constructor(x: String) { + parentProp = x + "#${outerProp}" + sideEffects += "#second#" + } + + init { + sideEffects += parentProp + "#third" + } + + protected constructor(x: Int): this(x.toString() + "#" + outerProp) { + parentProp += "#int" + sideEffects += "fourth#" + } + } + + inner class A2 : A1 { + var prop: String = "" + init { + sideEffects += outerProp + "#" + prop + "fifth" + } + + constructor(x: String): super(x + "#" + outerProp) { + prop = x + "#$outerProp" + sideEffects += "#sixth" + } + + init { + sideEffects += prop + "#seventh" + } + + constructor(x: Int): super(x + 1) { + prop += "$x#$outerProp#int" + sideEffects += "#eighth" + } + } +} + +fun box(): String { + val outer1 = Outer("propValue1") + val a1 = outer1.A2("abc") + if (a1.parentProp != "abc#propValue1#propValue1") return "fail1: ${a1.parentProp}" + if (a1.prop != "abc#propValue1") return "fail2: ${a1.prop}" + if (outer1.sideEffects != "propValue1#first#third#second#propValue1#fifth#seventh#sixth") return "fail1-sideEffects: ${outer1.sideEffects}" + + val outer2 = Outer("propValue2") + val a2 = outer2.A2(123) + if (a2.parentProp != "124#propValue2#propValue2#int") return "fail3: ${a2.parentProp}" + if (a2.prop != "123#propValue2#int") return "fail4: ${a2.prop}" + if (outer2.sideEffects != "propValue2#first#third#second#fourth#propValue2#fifth#seventh#eighth") return "fail2-sideEffects: ${outer2.sideEffects}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/localClasses.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/localClasses.kt new file mode 100644 index 00000000000..fb26a6ba6aa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/localClasses.kt @@ -0,0 +1,77 @@ +open class C(val grandParentProp: String) +fun box(): String { + var sideEffects: String = "" + var parentSideEffects: String = "" + val justForUsageInClosure = 7 + val justForUsageInParentClosure = "parentCaptured" + + abstract class B : C { + val parentProp: String + init { + sideEffects += "minus-one#" + parentSideEffects += "1" + } + protected constructor(arg: Int): super(justForUsageInParentClosure) { + parentProp = (arg).toString() + sideEffects += "0.5#" + parentSideEffects += "#" + justForUsageInParentClosure + } + protected constructor(arg1: Int, arg2: Int): super(justForUsageInParentClosure) { + parentProp = (arg1 + arg2).toString() + sideEffects += "0.7#" + parentSideEffects += "#3" + } + init { + sideEffects += "zero#" + parentSideEffects += "#4" + } + } + + class A : B { + var prop: String = "" + init { + sideEffects += prop + "first" + } + + constructor(x1: Int, x2: Int): super(x1, x2) { + prop = x1.toString() + sideEffects += "#third" + } + + init { + sideEffects += prop + "#second" + } + + constructor(x: Int): super(justForUsageInClosure + x) { + prop += "${x}#int" + sideEffects += "#fourth" + } + + constructor(): this(justForUsageInClosure) { + sideEffects += "#fifth" + } + + override fun toString() = "$prop#$parentProp#$grandParentProp" + } + + val a1 = A(5, 10).toString() + if (a1 != "5#15#parentCaptured") return "fail1: $a1" + if (sideEffects != "minus-one#zero#0.7#first#second#third") return "fail2: ${sideEffects}" + if (parentSideEffects != "1#4#3") return "fail3: ${parentSideEffects}" + + sideEffects = "" + parentSideEffects = "" + val a2 = A(123).toString() + if (a2 != "123#int#130#parentCaptured") return "fail1: $a2" + if (sideEffects != "minus-one#zero#0.5#first#second#fourth") return "fail4: ${sideEffects}" + if (parentSideEffects != "1#4#parentCaptured") return "fail5: ${parentSideEffects}" + + sideEffects = "" + parentSideEffects = "" + val a3 = A().toString() + if (a3 != "7#int#14#parentCaptured") return "fail6: $a3" + if (sideEffects != "minus-one#zero#0.5#first#second#fourth#fifth") return "fail7: ${sideEffects}" + if (parentSideEffects != "1#4#parentCaptured") return "fail8: ${parentSideEffects}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/superCallPrimary.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/superCallPrimary.kt new file mode 100644 index 00000000000..7225bc1af4f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/superCallPrimary.kt @@ -0,0 +1,53 @@ +var sideEffects: String = "" + +abstract class B protected constructor(val arg: Int) { + val parentProp: String + init { + sideEffects += "zero#" + parentProp = arg.toString() + } +} + +class A(x: Boolean) : B(if (x) 1 else 2) { + var prop: String = "" + init { + sideEffects += prop + "first" + } + + constructor(x: String): this(x == "abc") { + prop = x + sideEffects += "#third" + } + + init { + sideEffects += prop + "#second" + } + + constructor(x: Int): this(x < 0) { + prop += "${x}#int" + sideEffects += "#fourth" + } +} + +fun box(): String { + val a1 = A("abc") + if (a1.prop != "abc") return "fail0: ${a1.prop}" + if (a1.parentProp != "1") return "fail1: ${a1.parentProp}" + if (a1.arg != 1) return "fail1': ${a1.arg}" + if (sideEffects != "zero#first#second#third") return "fail2: ${sideEffects}" + + sideEffects = "" + val a2 = A(123) + if (a2.prop != "123#int") return "fail3: ${a2.prop}" + if (a2.parentProp != "2") return "fail4: ${a2.parentProp}" + if (a2.arg != 2) return "fail5': ${a2.arg}" + if (sideEffects != "zero#first#second#fourth") return "fail6: ${sideEffects}" + + sideEffects = "" + val a3 = A(false) + if (a3.prop != "") return "fail7: ${a3.prop}" + if (a3.parentProp != "2") return "fail8: ${a3.parentProp}" + if (a3.arg != 2) return "fail9': ${a3.arg}" + if (sideEffects != "zero#first#second") return "fail10: ${sideEffects}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/superCallSecondary.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/superCallSecondary.kt new file mode 100644 index 00000000000..e5d0064aa01 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/superCallSecondary.kt @@ -0,0 +1,64 @@ +var sideEffects: String = "" + +internal abstract class B { + val parentProp: String + init { + sideEffects += "minus-one#" + } + protected constructor(arg: Int) { + parentProp = (arg).toString() + sideEffects += "0.5#" + } + protected constructor(arg1: Int, arg2: Int) { + parentProp = (arg1 + arg2).toString() + sideEffects += "0.7#" + } + init { + sideEffects += "zero#" + } +} + +internal class A : B { + var prop: String = "" + init { + sideEffects += prop + "first" + } + + constructor(x1: Int, x2: Int): super(x1, x2) { + prop = x1.toString() + sideEffects += "#third" + } + + init { + sideEffects += prop + "#second" + } + + constructor(x: Int): super(3 + x) { + prop += "${x}#int" + sideEffects += "#fourth" + } + + constructor(): this(7) { + sideEffects += "#fifth" + } +} + +fun box(): String { + val a1 = A(5, 10) + if (a1.prop != "5") return "fail0: ${a1.prop}" + if (a1.parentProp != "15") return "fail1: ${a1.parentProp}" + if (sideEffects != "minus-one#zero#0.7#first#second#third") return "fail2: ${sideEffects}" + + sideEffects = "" + val a2 = A(123) + if (a2.prop != "123#int") return "fail3: ${a2.prop}" + if (a2.parentProp != "126") return "fail4: ${a2.parentProp}" + if (sideEffects != "minus-one#zero#0.5#first#second#fourth") return "fail5: ${sideEffects}" + + sideEffects = "" + val a3 = A() + if (a3.prop != "7#int") return "fail6: ${a3.prop}" + if (a3.parentProp != "10") return "fail7: ${a3.parentProp}" + if (sideEffects != "minus-one#zero#0.5#first#second#fourth#fifth") return "fail8: ${sideEffects}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/varargs.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/varargs.kt new file mode 100644 index 00000000000..39bfb8bf7a9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/varargs.kt @@ -0,0 +1,31 @@ +fun join(x: Array): String { + var result = "" + for (i in x) { + result += i + result += "#" + } + + return result +} + +open class B { + val parentProp: String + constructor(vararg x: String) { + parentProp = join(x) + } +} + +class A : B { + val prop: String + constructor(vararg x: String): super("0", *x, "4") { + prop = join(x) + } +} + +fun box(): String { + val a1 = A("1", "2", "3") + if (a1.prop != "1#2#3#") return "fail1: ${a1.prop}" + if (a1.parentProp != "0#1#2#3#4#") return "fail2: ${a1.parentProp}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withGenerics.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withGenerics.kt new file mode 100644 index 00000000000..20cd7ce3da7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withGenerics.kt @@ -0,0 +1,37 @@ +// TARGET_BACKEND: JVM +// FILE: WithGenerics.java + +class WithGenerics { + public static String foo1() { + A x = new A("OK"); + return x.toString(); + } + + public static String foo2() { + A x = new A(123); + return x.toString(); + } +} + +// FILE: WithGenerics.kt + +open class A { + val prop: String + constructor(x: String) { + prop = x + } + constructor(x: T) { + prop = x.toString() + } + + override fun toString() = prop +} + +fun box(): String { + val a1 = WithGenerics.foo1() + if (a1 != "OK") return "fail1: $a1" + val a2 = WithGenerics.foo2() + if (a2 != "123") return "fail2: $a2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withNonLocalReturn.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withNonLocalReturn.kt new file mode 100644 index 00000000000..97e4d24e68a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withNonLocalReturn.kt @@ -0,0 +1,24 @@ +// TODO enable for JS backend too when KT-14549 will be fixed +// IGNORE_BACKEND: JS, NATIVE + +inline fun run(block: () -> Unit) = block() + +class A { + val prop: Int + constructor(arg: Boolean) { + if (arg) { + prop = 1 + run { return } + throw RuntimeException("fail 0") + } + prop = 2 + } +} + +fun box(): String { + val a1 = A(true) + if (a1.prop != 1) return "fail1: ${a1.prop}" + val a2 = A(false) + if (a2.prop != 2) return "fail2: ${a2.prop}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withPrimary.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withPrimary.kt new file mode 100644 index 00000000000..28080ec08d1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withPrimary.kt @@ -0,0 +1,41 @@ +// TARGET_BACKEND: JVM +// FILE: WithPrimary.java + +class WithPrimary { + public static A test1() { + return new A("123", "abc"); + } + public static A test2() { + return new A(); + } + public static A test3() { + return new A("123", 456); + } + public static A test4() { + return new A(1.0); + } +} + +// FILE: WithPrimary.kt + +class A(val x: String = "def_x", val y: String = "1") { + constructor(x: String, y: Int): this(x, y.toString()) {} + constructor(x: Double): this(x.toString(), "def_y") {} + override fun toString() = "$x#$y" +} + +fun box(): String { + val test1 = WithPrimary.test1().toString() + if (test1 != "123#abc") return "fail1: $test1" + + val test2 = WithPrimary.test2().toString() + if (test2 != "def_x#1") return "fail2: $test2" + + val test3 = WithPrimary.test3().toString() + if (test3 != "123#456") return "fail3: $test3" + + val test4 = WithPrimary.test4().toString() + if (test4 != "1.0#def_y") return "fail4: $test4" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withReturn.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withReturn.kt new file mode 100644 index 00000000000..b6cb18cf2af --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withReturn.kt @@ -0,0 +1,18 @@ +class A { + val prop: Int + constructor(arg: Boolean) { + if (arg) { + prop = 1 + return + } + prop = 2 + } +} + +fun box(): String { + val a1 = A(true) + if (a1.prop != 1) return "fail1: ${a1.prop}" + val a2 = A(false) + if (a2.prop != 2) return "fail2: ${a2.prop}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withReturnUnit.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withReturnUnit.kt new file mode 100644 index 00000000000..956c6db367e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withReturnUnit.kt @@ -0,0 +1,18 @@ +class A { + val prop: Int + constructor(arg: Boolean) { + if (arg) { + prop = 1 + return Unit + } + prop = 2 + } +} + +fun box(): String { + val a1 = A(true) + if (a1.prop != 1) return "fail1: ${a1.prop}" + val a2 = A(false) + if (a2.prop != 2) return "fail2: ${a2.prop}" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withVarargs.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withVarargs.kt new file mode 100644 index 00000000000..84b0f3feba8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withVarargs.kt @@ -0,0 +1,34 @@ +// TARGET_BACKEND: JVM +// FILE: WithVarargs.java + +public class WithVarargs { + public static String foo() { + return new A("1", "2", "3").getProp(); + } +} + +// FILE: withVarargs.kt + +fun join(x: Array): String { + var result = "" + for (i in x) { + result += i + result += "#" + } + + return result +} + +class A { + val prop: String + constructor(vararg x: String) { + prop = join(x) + } +} + +fun box(): String { + val a1 = WithVarargs.foo() + if (a1 != "1#2#3#") return "fail1: ${a1}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withoutPrimary.kt b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withoutPrimary.kt new file mode 100644 index 00000000000..d455a57dba8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/secondaryConstructors/withoutPrimary.kt @@ -0,0 +1,41 @@ +// TARGET_BACKEND: JVM +// FILE: WithoutPrimary.java + +class WithoutPrimary { + public static A test1() { + return new A("123", "abc"); + } + public static A test3() { + return new A("123", 456); + } + public static A test4() { + return new A(1.0); + } +} + +// FILE: WithoutPrimary.kt + +class A { + val x: String + val y: String + constructor(x: String, y: String) { + this.x = x + this.y = y + } + constructor(x: String = "def_x", y: Int = 1): this(x, y.toString()) {} + constructor(x: Double): this(x.toString(), "def_y") {} + override fun toString() = "$x#$y" +} + +fun box(): String { + val test1 = WithoutPrimary.test1().toString() + if (test1 != "123#abc") return "fail1: $test1" + + val test3 = WithoutPrimary.test3().toString() + if (test3 != "123#456") return "fail3: $test3" + + val test4 = WithoutPrimary.test4().toString() + if (test4 != "1.0#def_y") return "fail4: $test4" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/smap/chainCalls.kt b/backend.native/tests/external/codegen/blackbox/smap/chainCalls.kt new file mode 100644 index 00000000000..73da8b97720 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/smap/chainCalls.kt @@ -0,0 +1,86 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FULL_JDK +package test +fun testProperLineNumber(): String { + var exceptionCount = 0; + try { + test(). + test(). + fail() + + } + catch(e: AssertionError) { + val entry = (e as java.lang.Throwable).getStackTrace()!!.get(1) + val actual = "${entry.getFileName()}:${entry.getLineNumber()}" + if ("chainCalls.kt:10" != actual) { + return "fail 1: ${actual}" + } + exceptionCount++ + } + + try { + call(). + test(). + fail() + } + catch(e: AssertionError) { + val entry = e.stackTrace!![1] + val actual = "${entry.getFileName()}:${entry.getLineNumber()}" + if ("chainCalls.kt:25" != actual) { + return "fail 2: ${actual}" + } + exceptionCount++ + } + + try { + test(). + fail() + } + catch(e: AssertionError) { + val entry = e.stackTrace!![1] + val actual = "${entry.getFileName()}:${entry.getLineNumber()}" + if ("chainCalls.kt:38" != actual) { + return "fail 3: ${actual}" + } + exceptionCount++ + } + + try { + test().fail() + } + catch(e: AssertionError) { + val entry = e.stackTrace!![1] + val actual = "${entry.getFileName()}:${entry.getLineNumber()}" + if ("chainCalls.kt:50" != actual) { + return "fail 4: ${actual}" + } + exceptionCount++ + } + + return if (exceptionCount == 4) "OK" else "fail" +} + +fun box(): String { + return testProperLineNumber() +} + +public fun checkEquals(p1: String, p2: String) { + throw AssertionError("fail") +} + +inline fun test(): String { + return "123" +} + +inline fun String.test(): String { + return "123" +} + +fun String.fail(): String { + throw AssertionError("fail") +} + +fun call(): String { + return "xxx" +} diff --git a/backend.native/tests/external/codegen/blackbox/smap/infixCalls.kt b/backend.native/tests/external/codegen/blackbox/smap/infixCalls.kt new file mode 100644 index 00000000000..eeab32d82e9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/smap/infixCalls.kt @@ -0,0 +1,66 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FULL_JDK +package test +fun testProperLineNumber(): String { + var exceptionCount = 0; + try { + test() fail + call() + } + catch(e: AssertionError) { + val entry = (e as java.lang.Throwable).getStackTrace()!!.get(1) + val actual = "${entry.getFileName()}:${entry.getLineNumber()}" + if ("infixCalls.kt:8" != actual) { + return "fail 1: ${actual}" + } + exceptionCount++ + } + + try { + call() fail + test() + } + catch(e: AssertionError) { + val entry = e.stackTrace!![1] + val actual = "${entry.getFileName()}:${entry.getLineNumber()}" + if ("infixCalls.kt:21" != actual) { + return "fail 1: ${actual}" + } + exceptionCount++ + } + + try { + call() fail test() + } + catch(e: AssertionError) { + val entry = e.stackTrace!![1] + val actual = "${entry.getFileName()}:${entry.getLineNumber()}" + if ("infixCalls.kt:34" != actual) { + return "fail 1: ${actual}" + } + exceptionCount++ + } + + return if (exceptionCount == 3) "OK" else "fail" +} + +fun box(): String { + return testProperLineNumber() +} + +public fun checkEquals(p1: String, p2: String) { + throw AssertionError("fail") +} + +inline fun test(): String { + return "123" +} + +infix fun String.fail(p: String): String { + throw AssertionError("fail") +} + +fun call(): String { + return "xxx" +} diff --git a/backend.native/tests/external/codegen/blackbox/smap/simpleCallWithParams.kt b/backend.native/tests/external/codegen/blackbox/smap/simpleCallWithParams.kt new file mode 100644 index 00000000000..8c0830bc26e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/smap/simpleCallWithParams.kt @@ -0,0 +1,110 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FULL_JDK +package test +fun testProperLineNumberAfterInline(): String { + var exceptionCount = 0; + try { + checkEquals(test(), + "12") + } + catch(e: AssertionError) { + val entry = (e as java.lang.Throwable).getStackTrace()!!.get(1) + val actual = "${entry.getFileName()}:${entry.getLineNumber()}" + if ("simpleCallWithParams.kt:8" != actual) { + return "fail 1: ${actual}" + } + exceptionCount++ + } + + try { + checkEquals("12", + test()) + } + catch(e: AssertionError) { + val entry = e.stackTrace!![1] + val actual = "${entry.getFileName()}:${entry.getLineNumber()}" + if ("simpleCallWithParams.kt:21" != actual) { + return "fail 2: ${actual}" + } + exceptionCount++ + } + + return if (exceptionCount == 2) "OK" else "fail" +} + +fun testProperLineForOtherParameters(): String { + var exceptionCount = 0; + try { + checkEquals(test(), + fail()) + } + catch(e: AssertionError) { + val entry = e.stackTrace!![1] + val actual = "${entry.getFileName()}:${entry.getLineNumber()}" + if ("simpleCallWithParams.kt:39" != actual) { + return "fail 3: ${actual}" + } + exceptionCount++ + + } + + try { + checkEquals(fail(), + test()) + } + catch(e: AssertionError) { + val entry = e.stackTrace!![1] + val actual = "${entry.getFileName()}:${entry.getLineNumber()}" + if ("simpleCallWithParams.kt:53" != actual) { + return "fail 4: ${actual}" + } + exceptionCount++ + } + + try { + checkEquals(fail(), test()) + } + catch(e: AssertionError) { + val entry = e.stackTrace!![1] + val actual = "${entry.getFileName()}:${entry.getLineNumber()}" + if ("simpleCallWithParams.kt:66" != actual) { + return "fail 5: ${actual}" + } + exceptionCount++ + } + + try { + checkEquals(fail(), test()) + } + catch(e: AssertionError) { + val entry = e.stackTrace!![1] + val actual = "${entry.getFileName()}:${entry.getLineNumber()}" + if ("simpleCallWithParams.kt:78" != actual) { + return "fail 6: ${actual}" + } + exceptionCount++ + } + + return if (exceptionCount == 4) "OK" else "fail" +} + + +fun box(): String { + val res = testProperLineNumberAfterInline() + if (res != "OK") return "$res" + + return testProperLineForOtherParameters() +} + +public fun checkEquals(p1: String, p2: String) { + throw AssertionError("fail") +} + +inline fun test(): String { + return "123" +} + +fun fail(): String { + throw AssertionError("fail") +} diff --git a/backend.native/tests/external/codegen/blackbox/smartCasts/falseSmartCast.kt b/backend.native/tests/external/codegen/blackbox/smartCasts/falseSmartCast.kt new file mode 100644 index 00000000000..cfdcf7e1e7c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/smartCasts/falseSmartCast.kt @@ -0,0 +1,17 @@ +open class SuperFoo { + public fun bar(): String { + if (this is Foo) { + superFoo() // Smart cast + return baz() // Cannot be cast + } + return baz() + } + + public fun baz() = "OK" +} + +class Foo : SuperFoo() { + public fun superFoo() {} +} + +fun box(): String = Foo().bar() \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/smartCasts/genericIntersection.kt b/backend.native/tests/external/codegen/blackbox/smartCasts/genericIntersection.kt new file mode 100644 index 00000000000..51c34682f0e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/smartCasts/genericIntersection.kt @@ -0,0 +1,9 @@ +// See also KT-7801 +class A + +fun test(v: T): T { + val a: T = if (v !is A) v else v + return a +} + +fun box() = test("OK") diff --git a/backend.native/tests/external/codegen/blackbox/smartCasts/genericSet.kt b/backend.native/tests/external/codegen/blackbox/smartCasts/genericSet.kt new file mode 100644 index 00000000000..48350f84309 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/smartCasts/genericSet.kt @@ -0,0 +1,13 @@ +class Wrapper(var x: T) + +inline fun change(w: Wrapper, x: Any?) { + if (x is T) { + w.x = x + } +} + +fun box(): String { + val w = Wrapper("FAIL") + change(w, "OK") + return w.x +} diff --git a/backend.native/tests/external/codegen/blackbox/smartCasts/implicitExtensionReceiver.kt b/backend.native/tests/external/codegen/blackbox/smartCasts/implicitExtensionReceiver.kt new file mode 100644 index 00000000000..f315a202bdb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/smartCasts/implicitExtensionReceiver.kt @@ -0,0 +1,7 @@ +class A { + fun foo() = "OK" +} + +fun A?.bar() = if (this != null) foo() else "FAIL" + +fun box() = A().bar() diff --git a/backend.native/tests/external/codegen/blackbox/smartCasts/implicitMemberReceiver.kt b/backend.native/tests/external/codegen/blackbox/smartCasts/implicitMemberReceiver.kt new file mode 100644 index 00000000000..f38fa9fd9b5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/smartCasts/implicitMemberReceiver.kt @@ -0,0 +1,20 @@ +open class A { + open val a = "OK" +} + +class B : A() { + override val a = "FAIL" + fun foo() = "CRUSH" +} + +class C { + fun A?.complex(): String { + if (this is B) return foo() + else if (this != null) return a + else return "???" + } + + fun bar() = A().complex() +} + +fun box() = C().bar() diff --git a/backend.native/tests/external/codegen/blackbox/smartCasts/implicitReceiver.kt b/backend.native/tests/external/codegen/blackbox/smartCasts/implicitReceiver.kt new file mode 100644 index 00000000000..911f53248c5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/smartCasts/implicitReceiver.kt @@ -0,0 +1,13 @@ +open class A { + class B : A() { + val a = "FAIL" + } + + fun foo(): String { + if (this is B) return a + return "OK" + } +} + + +fun box(): String = A().foo() diff --git a/backend.native/tests/external/codegen/blackbox/smartCasts/implicitReceiverInWhen.kt b/backend.native/tests/external/codegen/blackbox/smartCasts/implicitReceiverInWhen.kt new file mode 100644 index 00000000000..ce31ad2d9f3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/smartCasts/implicitReceiverInWhen.kt @@ -0,0 +1,11 @@ +open class A { + fun f(): String = + when (this) { + is B -> x + else -> "FAIL" + } +} + +class B(val x: String) : A() + +fun box() = B("OK").f() diff --git a/backend.native/tests/external/codegen/blackbox/smartCasts/implicitToGrandSon.kt b/backend.native/tests/external/codegen/blackbox/smartCasts/implicitToGrandSon.kt new file mode 100644 index 00000000000..588cc9ff24d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/smartCasts/implicitToGrandSon.kt @@ -0,0 +1,13 @@ +open class A { + open fun foo() = "FAIL" + + fun bar() = if (this is C) foo() else foo() +} + +open class B : A() + +open class C : B() { + override fun foo() = "OK" +} + +fun box() = C().bar() diff --git a/backend.native/tests/external/codegen/blackbox/smartCasts/lambdaArgumentWithoutType.kt b/backend.native/tests/external/codegen/blackbox/smartCasts/lambdaArgumentWithoutType.kt new file mode 100644 index 00000000000..b385b115457 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/smartCasts/lambdaArgumentWithoutType.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class Foo(val s: String) +fun foo(): Foo? = Foo("OK") + +fun run(f: () -> T): T = f() + +val foo: Foo = run { + val x = foo() + if (x == null) throw Exception() + x +} + +fun box() = foo.s diff --git a/backend.native/tests/external/codegen/blackbox/smartCasts/nullSmartCast.kt b/backend.native/tests/external/codegen/blackbox/smartCasts/nullSmartCast.kt new file mode 100644 index 00000000000..1b74cbd9ea3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/smartCasts/nullSmartCast.kt @@ -0,0 +1,8 @@ +fun String?.foo() = this ?: "OK" + +fun foo(i: Int?): String { + if (i == null) return i.foo() + return "$i" +} + +fun box() = foo(null) diff --git a/backend.native/tests/external/codegen/blackbox/smartCasts/smartCastInsideIf.kt b/backend.native/tests/external/codegen/blackbox/smartCasts/smartCastInsideIf.kt new file mode 100644 index 00000000000..10d4a4c76c8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/smartCasts/smartCastInsideIf.kt @@ -0,0 +1,15 @@ +class A(val s: String = "FAIL") + +private fun foo(a: A?, aOther: A?): A { + return if (a == null) { + A() + } + else { + if (aOther == null) { + return A() + } + aOther + } +} + +fun box() = foo(A("???"), A("OK")).s diff --git a/backend.native/tests/external/codegen/blackbox/smartCasts/whenSmartCast.kt b/backend.native/tests/external/codegen/blackbox/smartCasts/whenSmartCast.kt new file mode 100644 index 00000000000..8069048ce00 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/smartCasts/whenSmartCast.kt @@ -0,0 +1,9 @@ +fun baz(s: String?): Int { + if (s == null) return 0 + return when(s) { + "abc" -> s + else -> "xyz" + }.length +} + +fun box() = if (baz("abc") == 3 && baz("") == 3 && baz(null) == 0) "OK" else "FAIL" diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/bridgeNotEmptyMap.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/bridgeNotEmptyMap.kt new file mode 100644 index 00000000000..bdc90a71a2c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/bridgeNotEmptyMap.kt @@ -0,0 +1,37 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +private object NotEmptyMap : MutableMap { + override fun containsKey(key: Any): Boolean = true + override fun containsValue(value: Int): Boolean = true + + // non-special bridges get(Object)Integer -> get(Object)I + override fun get(key: Any): Int = 1 + override fun remove(key: Any): Int = 1 + + override val size: Int get() = 0 + override fun isEmpty(): Boolean = true + override fun put(key: Any, value: Int): Int? = throw UnsupportedOperationException() + override fun putAll(from: Map): Unit = throw UnsupportedOperationException() + override fun clear(): Unit = throw UnsupportedOperationException() + override val entries: MutableSet> get() = null!! + override val keys: MutableSet get() = null!! + override val values: MutableCollection get() = null!! +} + + +fun box(): String { + val n = NotEmptyMap as MutableMap + + if (n.get(null) != null) return "fail 1" + if (n.containsKey(null)) return "fail 2" + if (n.containsValue(null)) return "fail 3" + if (n.remove(null) != null) return "fail 4" + + if (n.get(1) == null) return "fail 5" + if (!n.containsKey("")) return "fail 6" + if (!n.containsValue(3)) return "fail 7" + if (n.remove("") == null) return "fail 8" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/bridges.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/bridges.kt new file mode 100644 index 00000000000..3b26586b311 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/bridges.kt @@ -0,0 +1,104 @@ + +interface A0 { + val size: Int get() = 56 +} + +class B0 : Collection, A0 { + override fun isEmpty() = throw UnsupportedOperationException() + override fun contains(o: String) = throw UnsupportedOperationException() + override fun iterator() = throw UnsupportedOperationException() + override fun containsAll(c: Collection) = throw UnsupportedOperationException() + override val size: Int + get() = super.size +} + +open class A1 { + val size: Int = 56 +} + +class B1 : Collection, A1() { + override fun isEmpty() = throw UnsupportedOperationException() + override fun contains(o: String) = throw UnsupportedOperationException() + override fun iterator() = throw UnsupportedOperationException() + override fun containsAll(c: Collection) = throw UnsupportedOperationException() +} + +interface I2 { + val size: Int +} + +val list = ArrayList() + +class B2 : ArrayList(list), I2 + +interface I3 { + val size: T +} + +class B3 : ArrayList(list), I3 + +interface I4 { + val size: T get() = 56 as T +} + +class B4 : Collection, I4 { + override fun isEmpty() = throw UnsupportedOperationException() + override fun contains(o: String) = throw UnsupportedOperationException() + override fun iterator() = throw UnsupportedOperationException() + override fun containsAll(c: Collection) = throw UnsupportedOperationException() + override val size: Int + get() = super.size +} + +interface I5 : Collection { + override val size: Int get() = 56 +} + +class B5 : I5 { + override fun isEmpty() = throw UnsupportedOperationException() + override fun contains(o: String) = throw UnsupportedOperationException() + override fun iterator() = throw UnsupportedOperationException() + override fun containsAll(c: Collection) = throw UnsupportedOperationException() +} + +fun box(): String { + list.add("1") + + val b0 = B0() + if (b0.size != 56) return "fail 0: ${b0.size}" + var x: Collection = B0() + if (x.size != 56) return "fail 00: ${x.size}" + val a0: A0 = b0 + if (a0.size != 56) return "fail 000: ${a0.size}" + + val b1 = B1() + if (b1.size != 56) return "fail 1: ${b1.size}" + x = B1() + if (x.size != 56) return "fail 2: ${x.size}" + + val b2 = B2() + if (b2.size != 1) return "fail 3: ${b2.size}" + x = B2() + if (x.size != 1) return "fail 4: ${x.size}" + val i2: I2 = b2 + if (i2.size != 1) return "fail 5: ${i2.size}" + + val b3 = B3() + if (b3.size != 1) return "fail 6: ${b3.size}" + x = B3() + if (x.size != 1) return "fail 7: ${x.size}" + val i3: I3 = b3 + if (i3.size != 1) return "fail 8: ${i3.size}" + + val b4 = B4() + if (b4.size != 56) return "fail 9: ${b4.size}" + x = B4() + if (x.size != 56) return "fail 10: ${x.size}" + + val b5 = B5() + if (b5.size != 56) return "fail 11: ${b5.size}" + x = B5() + if (x.size != 56) return "fail 12: ${x.size}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/collectionImpl.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/collectionImpl.kt new file mode 100644 index 00000000000..0e145b90460 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/collectionImpl.kt @@ -0,0 +1,97 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class A1 : MutableCollection { + override val size: Int + get() = 56 + + override fun isEmpty(): Boolean { + throw UnsupportedOperationException() + } + + override fun contains(o: String): Boolean { + throw UnsupportedOperationException() + } + + override fun iterator(): MutableIterator { + throw UnsupportedOperationException() + } + + override fun containsAll(c: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun add(e: String): Boolean { + throw UnsupportedOperationException() + } + + override fun remove(o: String): Boolean { + throw UnsupportedOperationException() + } + + override fun addAll(c: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun removeAll(c: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun retainAll(c: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun clear() { + throw UnsupportedOperationException() + } +} + +class A2 : java.util.AbstractCollection() { + override val size: Int + get() = 56 + + override fun iterator(): MutableIterator { + throw UnsupportedOperationException() + } +} + +class A3 : java.util.ArrayList() { + override val size: Int + get() = 56 +} + +interface Sized { + val size: Int +} + +class A4 : java.util.ArrayList(), Sized { + override val size: Int + get() = 56 +} + +fun check56(x: Collection) { + if (x.size != 56) throw java.lang.RuntimeException("fail ${x.size}") +} + +fun box(): String { + val a1 = A1() + if (a1.size != 56) return "fail 1: ${a1.size}" + check56(a1) + + val a2 = A2() + if (a2.size != 56) return "fail 2: ${a2.size}" + check56(a2) + + val a3 = A3() + if (a3.size != 56) return "fail 3: ${a3.size}" + check56(a3) + + val a4 = A4() + if (a4.size != 56) return "fail 4: ${a4.size}" + check56(a4) + + val sized: Sized = a4 + if (sized.size != 56) return "fail 5: ${a4.size}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/commonBridgesTarget.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/commonBridgesTarget.kt new file mode 100644 index 00000000000..c5ffa3b61d9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/commonBridgesTarget.kt @@ -0,0 +1,25 @@ + +open class Base() : HashSet() { + override fun remove(element: Target): Boolean { + return true + } +} + +class Derived : Base() { + // common "synthetic bridge override fun remove(element: DatabaseEntity): Boolean" should call + // `INVOKEVIRTUAL remove(Issue)` + // instead of `INVOKEVIRTUAL remove(OBJECT)` + override fun remove(element: Issue): Boolean { + return super.remove(element) + } +} + +open class DatabaseEntity +class Issue: DatabaseEntity() + +fun box(): String { + val sprintIssues = Derived() + if (!sprintIssues.remove(Issue())) return "Fail" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/emptyList.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/emptyList.kt new file mode 100644 index 00000000000..d7c4c262b7e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/emptyList.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +private object EmptyList : List { + override fun contains(element: Nothing): Boolean = false + override fun containsAll(elements: Collection): Boolean = elements.isEmpty() + override fun indexOf(element: Nothing): Int = -2 + override fun lastIndexOf(element: Nothing): Int = -2 + + override val size: Int get() = 0 + override fun isEmpty(): Boolean = true + + override fun iterator(): Iterator = throw UnsupportedOperationException() + override fun get(index: Int): Nothing = throw UnsupportedOperationException() + override fun listIterator(): ListIterator = throw UnsupportedOperationException() + override fun listIterator(index: Int): ListIterator = throw UnsupportedOperationException() + override fun subList(fromIndex: Int, toIndex: Int): List = throw UnsupportedOperationException() +} + +fun box(): String { + val n = EmptyList as List + + if (n.contains("")) return "fail 1" + if (n.indexOf("") != -1) return "fail 2" + if (n.lastIndexOf("") != -1) return "fail 3" + + val nullAny = EmptyList as List + + if (nullAny.contains(null)) return "fail 4" + if (nullAny.indexOf(null) != -1) return "fail 5" + if (nullAny.lastIndexOf(null) != -1) return "fail 6" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/emptyMap.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/emptyMap.kt new file mode 100644 index 00000000000..c0770bd6b2a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/emptyMap.kt @@ -0,0 +1,22 @@ +private object EmptyMap : Map { + override val size: Int get() = 0 + override fun isEmpty(): Boolean = true + + override fun containsKey(key: Any): Boolean = false + override fun containsValue(value: Nothing): Boolean = false + override fun get(key: Any): Nothing? = null + override val entries: Set> get() = null!! + override val keys: Set get() = null!! + override val values: Collection get() = null!! +} + + +fun box(): String { + val n = EmptyMap as Map + + if (n.get(null) != null) return "fail 1" + if (n.containsKey(null)) return "fail 2" + if (n.containsValue(null)) return "fail 3" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/emptyStringMap.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/emptyStringMap.kt new file mode 100644 index 00000000000..fd4953af8ec --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/emptyStringMap.kt @@ -0,0 +1,21 @@ +private object EmptyStringMap : Map { + override val size: Int get() = 0 + override fun isEmpty(): Boolean = true + + override fun containsKey(key: String): Boolean = false + override fun containsValue(value: Nothing): Boolean = false + override fun get(key: String): Nothing? = null + override val entries: Set> get() = null!! + override val keys: Set get() = null!! + override val values: Collection get() = null!! +} + +fun box(): String { + val n = EmptyStringMap as Map + + if (n.get(null) != null) return "fail 1" + if (n.containsKey(null)) return "fail 2" + if (n.containsValue(null)) return "fail 3" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/entrySetSOE.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/entrySetSOE.kt new file mode 100644 index 00000000000..15a676453c7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/entrySetSOE.kt @@ -0,0 +1,14 @@ + +open class Map1 : HashMap() +class Map2 : Map1() +fun box(): String { + val m = Map2() + if (m.entries.size != 0) return "fail 1" + + m.put("56", "OK") + val x = m.entries.iterator().next() + + if (x.key != "56" || x.value != "OK") return "fail 2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/enumAsOrdinaled.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/enumAsOrdinaled.kt new file mode 100644 index 00000000000..6b3eda01d77 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/enumAsOrdinaled.kt @@ -0,0 +1,16 @@ +interface Ordinaled { + val ordinal: Int +} + +enum class A : Ordinaled { + X +} + + +fun box(): String { + val result = (A.X as Ordinaled).ordinal + + if (result != 0) return "fail 1: $result" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/explicitSuperCall.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/explicitSuperCall.kt new file mode 100644 index 00000000000..334b9521a49 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/explicitSuperCall.kt @@ -0,0 +1,10 @@ +class A : ArrayList() { + override val size: Int get() = super.size + 56 +} + +fun box(): String { + val a = A() + if (a.size != 56) return "fail: ${a.size}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/irrelevantRemoveAtOverride.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/irrelevantRemoveAtOverride.kt new file mode 100644 index 00000000000..0e385c6fc30 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/irrelevantRemoveAtOverride.kt @@ -0,0 +1,104 @@ +interface Container { + fun removeAt(x: Int): String +} + +open class ContainerImpl : Container { + override fun removeAt(x: Int) = "abc" +} + +class A : ContainerImpl(), MutableList { + override fun isEmpty(): Boolean { + throw UnsupportedOperationException() + } + + override val size: Int + get() = throw UnsupportedOperationException() + + override fun contains(element: String): Boolean { + throw UnsupportedOperationException() + } + + override fun containsAll(elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun get(index: Int): String { + throw UnsupportedOperationException() + } + + override fun indexOf(element: String): Int { + throw UnsupportedOperationException() + } + + override fun lastIndexOf(element: String): Int { + throw UnsupportedOperationException() + } + + override fun add(element: String): Boolean { + throw UnsupportedOperationException() + } + + override fun remove(element: String): Boolean { + throw UnsupportedOperationException() + } + + override fun addAll(elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun addAll(index: Int, elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun removeAll(elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun retainAll(elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun clear() { + throw UnsupportedOperationException() + } + + override fun set(index: Int, element: String): String { + throw UnsupportedOperationException() + } + + override fun add(index: Int, element: String) { + throw UnsupportedOperationException() + } + + override fun listIterator(): MutableListIterator { + throw UnsupportedOperationException() + } + + override fun listIterator(index: Int): MutableListIterator { + throw UnsupportedOperationException() + } + + override fun subList(fromIndex: Int, toIndex: Int): MutableList { + throw UnsupportedOperationException() + } + + override fun iterator(): MutableIterator { + throw UnsupportedOperationException() + } +} + +fun box(): String { + val a = A() + if (a.removeAt(0) != "abc") return "fail 1" + + val l: MutableList = a + if (l.removeAt(0) != "abc") return "fail 2" + + val anyList: MutableList = a as MutableList + if (anyList.removeAt(0) != "abc") return "fail 3" + + val container: Container = a + if (container.removeAt(0) != "abc") return "fail 4" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/maps.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/maps.kt new file mode 100644 index 00000000000..d3dedeef878 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/maps.kt @@ -0,0 +1,41 @@ +class A : Map { + override val size: Int get() = 56 + + override fun isEmpty(): Boolean { + throw UnsupportedOperationException() + } + + override fun containsKey(key: String): Boolean { + throw UnsupportedOperationException() + } + + override fun containsValue(value: String): Boolean { + throw UnsupportedOperationException() + } + + override fun get(key: String): String? { + throw UnsupportedOperationException() + } + + override val keys: Set get() { + throw UnsupportedOperationException() + } + + override val values: Collection get() { + throw UnsupportedOperationException() + } + + override val entries: Set> get() { + throw UnsupportedOperationException() + } +} + +fun box(): String { + val a = A() + if (a.size != 56) return "fail 1: ${a.size}" + + val x: Map = a + if (x.size != 56) return "fail 2: ${x.size}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/noSpecialBridgeInSuperClass.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/noSpecialBridgeInSuperClass.kt new file mode 100644 index 00000000000..df49fe5a5cb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/noSpecialBridgeInSuperClass.kt @@ -0,0 +1,59 @@ +var result = "" + +public abstract class AbstractFoo : Map { + override operator fun get(key: K): V? { + result = "AbstractFoo" + return null + } + + override val size: Int + get() = throw UnsupportedOperationException() + + override fun isEmpty(): Boolean { + throw UnsupportedOperationException() + } + + override fun containsKey(key: K): Boolean { + throw UnsupportedOperationException() + } + + override fun containsValue(value: V): Boolean { + throw UnsupportedOperationException() + } + + override val keys: Set + get() = throw UnsupportedOperationException() + override val values: Collection + get() = throw UnsupportedOperationException() + override val entries: Set> + get() = throw UnsupportedOperationException() +} + +public open class StringFoo : AbstractFoo() { + override operator fun get(key: String): E? { + result = "StringFoo" + return null + } +} + +public class IntFoo : AbstractFoo() { + override operator fun get(key: Int): E? { + result = "IntFoo" + return null + } +} + +public class AnyFoo : AbstractFoo() {} + +fun box(): String { + StringFoo().get("") + if (result != "StringFoo") return "fail 1: $result" + + IntFoo().get(1) + if (result != "IntFoo") return "fail 2: $result" + + AnyFoo().get(null) + if (result != "AbstractFoo") return "fail 3: $result" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/notEmptyListAny.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/notEmptyListAny.kt new file mode 100644 index 00000000000..7bb922953d7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/notEmptyListAny.kt @@ -0,0 +1,46 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +private object NotEmptyList : MutableList { + override fun contains(element: Any): Boolean = true + override fun indexOf(element: Any): Int = 0 + override fun lastIndexOf(element: Any): Int = 0 + override fun remove(element: Any): Boolean = true + + override val size: Int + get() = throw UnsupportedOperationException() + + override fun containsAll(elements: Collection): Boolean = elements.isEmpty() + override fun isEmpty(): Boolean = throw UnsupportedOperationException() + override fun get(index: Int): Any = throw UnsupportedOperationException() + override fun add(element: Any): Boolean = throw UnsupportedOperationException() + override fun addAll(elements: Collection): Boolean = throw UnsupportedOperationException() + override fun addAll(index: Int, elements: Collection): Boolean = throw UnsupportedOperationException() + override fun removeAll(elements: Collection): Boolean = throw UnsupportedOperationException() + override fun retainAll(elements: Collection): Boolean = throw UnsupportedOperationException() + override fun clear(): Unit = throw UnsupportedOperationException() + override fun set(index: Int, element: Any): Any = throw UnsupportedOperationException() + override fun add(index: Int, element: Any): Unit = throw UnsupportedOperationException() + override fun removeAt(index: Int): Any = throw UnsupportedOperationException() + override fun listIterator(): MutableListIterator = throw UnsupportedOperationException() + override fun listIterator(index: Int): MutableListIterator = throw UnsupportedOperationException() + override fun subList(fromIndex: Int, toIndex: Int): MutableList = throw UnsupportedOperationException() + override fun iterator(): MutableIterator = throw UnsupportedOperationException() +} + +fun box(): String { + val n = NotEmptyList as MutableList + + if (n.contains(null)) return "fail 1" + if (n.indexOf(null) != -1) return "fail 2" + if (n.lastIndexOf(null) != -1) return "fail 3" + + if (!n.contains("")) return "fail 3" + if (n.indexOf("") != 0) return "fail 4" + if (n.lastIndexOf("") != 0) return "fail 5" + + if (n.remove(null)) return "fail 6" + if (!n.remove("")) return "fail 7" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/notEmptyMap.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/notEmptyMap.kt new file mode 100644 index 00000000000..875c615b4ca --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/notEmptyMap.kt @@ -0,0 +1,35 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +private object NotEmptyMap : MutableMap { + override fun containsKey(key: Any): Boolean = true + override fun containsValue(value: Any): Boolean = true + override fun get(key: Any): Any? = Any() + override fun remove(key: Any): Any? = Any() + + override val size: Int get() = 0 + override fun isEmpty(): Boolean = true + override fun put(key: Any, value: Any): Any? = throw UnsupportedOperationException() + override fun putAll(from: Map): Unit = throw UnsupportedOperationException() + override fun clear(): Unit = throw UnsupportedOperationException() + override val entries: MutableSet> get() = null!! + override val keys: MutableSet get() = null!! + override val values: MutableCollection get() = null!! +} + + +fun box(): String { + val n = NotEmptyMap as MutableMap + + if (n.get(null) != null) return "fail 1" + if (n.containsKey(null)) return "fail 2" + if (n.containsValue(null)) return "fail 3" + if (n.remove(null) != null) return "fail 4" + + if (n.get("") == null) return "fail 5" + if (!n.containsKey("")) return "fail 6" + if (!n.containsValue("")) return "fail 7" + if (n.remove("") == null) return "fail 8" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/redundantStubForSize.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/redundantStubForSize.kt new file mode 100644 index 00000000000..df0376cc9cb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/redundantStubForSize.kt @@ -0,0 +1,28 @@ +open class A1 { + open val size: Int = 56 +} + +class A2 : A1(), Collection { + // No 'getSize()' method should be generated in A2 + + override fun contains(element: String): Boolean { + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun containsAll(elements: Collection): Boolean { + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun isEmpty(): Boolean { + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun iterator(): Iterator { + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. + } +} + +fun box(): String { + if (A2().size != 56) return "fail 1" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/removeAtTwoSpecialBridges.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/removeAtTwoSpecialBridges.kt new file mode 100644 index 00000000000..86f4b09d05c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/removeAtTwoSpecialBridges.kt @@ -0,0 +1,96 @@ +open class A0 : MutableList { + override fun add(element: E): Boolean { + throw UnsupportedOperationException() + } + + override fun add(index: Int, element: E) { + throw UnsupportedOperationException() + } + + override fun addAll(index: Int, elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun addAll(elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun clear() { + throw UnsupportedOperationException() + } + + override fun listIterator(): MutableListIterator { + throw UnsupportedOperationException() + } + + override fun listIterator(index: Int): MutableListIterator { + throw UnsupportedOperationException() + } + + override fun remove(element: E): Boolean { + throw UnsupportedOperationException() + } + + override fun removeAll(elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun removeAt(index: Int): E = "K" as E + + override fun retainAll(elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun set(index: Int, element: E): E { + throw UnsupportedOperationException() + } + + override fun subList(fromIndex: Int, toIndex: Int): MutableList { + throw UnsupportedOperationException() + } + + override val size: Int + get() = throw UnsupportedOperationException() + + override fun contains(element: E): Boolean { + throw UnsupportedOperationException() + } + + override fun containsAll(elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + override fun get(index: Int): E { + throw UnsupportedOperationException() + } + + override fun indexOf(element: E): Int { + throw UnsupportedOperationException() + } + + override fun isEmpty(): Boolean { + throw UnsupportedOperationException() + } + + override fun lastIndexOf(element: E): Int { + throw UnsupportedOperationException() + } + + override fun iterator(): MutableIterator { + throw UnsupportedOperationException() + } +} + +class A1() : A0() { + override fun removeAt(p0: Int): String = "O" +} + +class A2 : A0() + +// Basically this test checks that no redundant special bridges were generated (i.e. no VerifyError happens) +fun box(): String { + val a1 = A1() + val a2 = A2() + + return a1.removeAt(123) + a2.removeAt(456) +} diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/throwable.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/throwable.kt new file mode 100644 index 00000000000..e4040a63794 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/throwable.kt @@ -0,0 +1,10 @@ +fun box(): String { + try { + throw Throwable("OK", null) + } catch (t: Throwable) { + if (t.cause != null) return "fail 1" + return t.message!! + } + + return "fail 2" +} diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/throwableImpl.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/throwableImpl.kt new file mode 100644 index 00000000000..2f6aeaa6b55 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/throwableImpl.kt @@ -0,0 +1,21 @@ +class MyThrowable(message: String? = null, cause: Throwable? = null) : Throwable(message, cause) { + + override val message: String? + get() = "My message: " + super.message + + override val cause: Throwable? + get() = super.cause ?: this + +} + +fun box(): String { + try { + throw MyThrowable("test") + } catch (t: MyThrowable) { + if (t.cause != t) return "fail t.cause" + if (t.message != "My message: test") return "fail t.message" + return "OK" + } + + return "fail: MyThrowable wasn't catched." +} diff --git a/backend.native/tests/external/codegen/blackbox/specialBuiltins/valuesInsideEnum.kt b/backend.native/tests/external/codegen/blackbox/specialBuiltins/valuesInsideEnum.kt new file mode 100644 index 00000000000..ee008bfcf82 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/specialBuiltins/valuesInsideEnum.kt @@ -0,0 +1,8 @@ +enum class Variants { + O, K; + companion object { + val valueStr = values()[0].name + Variants.values()[1].name + } +} + +fun box() = Variants.valueStr diff --git a/backend.native/tests/external/codegen/blackbox/statics/anonymousInitializerIObject.kt b/backend.native/tests/external/codegen/blackbox/statics/anonymousInitializerIObject.kt new file mode 100644 index 00000000000..72aa88ec05b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/statics/anonymousInitializerIObject.kt @@ -0,0 +1,11 @@ +object Foo { + val bar: String + + init { + bar = "OK" + } +} + +fun box(): String { + return Foo.bar +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/statics/anonymousInitializerInClassObject.kt b/backend.native/tests/external/codegen/blackbox/statics/anonymousInitializerInClassObject.kt new file mode 100644 index 00000000000..3b3559b2895 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/statics/anonymousInitializerInClassObject.kt @@ -0,0 +1,13 @@ +class Foo { + companion object { + val bar: String + + init { + bar = "OK" + } + } +} + +fun box(): String { + return Foo.bar +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/statics/fields.kt b/backend.native/tests/external/codegen/blackbox/statics/fields.kt new file mode 100644 index 00000000000..a32fda1f232 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/statics/fields.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: Child.java + +class Child extends Parent { + public static int b = 3; + public static int c = 4; +} + +// FILE: Parent.java + +class Parent { + public static int a = 1; + public static int b = 2; +} + +// FILE: test.kt + +fun box(): String { + if (Parent.a != 1) return "expected Parent.a == 1" + if (Parent.b != 2) return "expected Parent.b == 2" + if (Child.a != 1) return "expected Child.a == 1" + if (Child.b != 3) return "expected Child.b == 3" + if (Child.c != 4) return "expected Child.c == 4" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/statics/functions.kt b/backend.native/tests/external/codegen/blackbox/statics/functions.kt new file mode 100644 index 00000000000..0a2e6767fdb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/statics/functions.kt @@ -0,0 +1,36 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: Child.java + +class Child extends Parent { + public static String bar() { + return "Child.bar"; + } + public static String baz() { + return "Child.baz"; + } +} + +// FILE: Parent.java + +class Parent { + public static String foo() { + return "Parent.foo"; + } + public static String baz() { + return "Parent.baz"; + } +} + +// FILE: test.kt + +fun box(): String { + if (Parent.foo() != "Parent.foo") return "expected: Parent.foo" + if (Parent.baz() != "Parent.baz") return "expected: Parent.baz" + if (Child.foo() != "Parent.foo") return "expected: Child.foo() != Parent.foo" + if (Child.baz() != "Child.baz") return "expected: Child.baz" + if (Child.bar() != "Child.bar") return "expected: Child.bar" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/statics/hidePrivateByPublic.kt b/backend.native/tests/external/codegen/blackbox/statics/hidePrivateByPublic.kt new file mode 100644 index 00000000000..6b6e3642663 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/statics/hidePrivateByPublic.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: Child.java + +class Child extends Parent { + public static String a = "2"; + public static String foo() { + return "Child.foo()"; + } + public static String foo(int i) { + return "Child.foo(int)"; + } +} + +// FILE: Parent.java + +class Parent { + private static int a = 1; + private static String foo() { + return "Parent.foo"; + } +} + +// FILE: test.kt + +fun box(): String { + if (Child.a != "2") return "Fail #1" + if (Child.foo() != "Child.foo()") return "Fail #2" + if (Child.foo(1) != "Child.foo(int)") return "Fail #3" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/statics/incInClassObject.kt b/backend.native/tests/external/codegen/blackbox/statics/incInClassObject.kt new file mode 100644 index 00000000000..fe763170399 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/statics/incInClassObject.kt @@ -0,0 +1,73 @@ +class A { + companion object { + private var r: Int = 1; + + fun test(): Int { + r++ + ++r + return r + } + + var holder: String = "" + + var r2: Int = 1; + get() { + holder += "getR2" + return field + } + + fun test2() : Int { + r2++ + ++r2 + return r2 + } + + var r3: Int = 1; + set(p: Int) { + holder += "setR3" + field = p + } + + fun test3() : Int { + r3++ + ++r3 + return r3 + } + + var r4: Int = 1; + get() { + holder += "getR4" + return field + } + set(p: Int) { + holder += "setR4" + field = p + } + + fun test4() : Int { + r4++ + holder += ":" + ++r4 + return r4 + } + } +} + +fun box() : String { + val p = A.test() + if (p != 3) return "fail 1: $p" + + val p2 = A.test2() + var holderValue = A.holder + if (p2 != 3 || holderValue != "getR2getR2getR2getR2") return "fail 2: $p2 ${holderValue}" + + A.holder = "" + val p3 = A.test3() + if (p3 != 3 || A.holder != "setR3setR3") return "fail 3: $p3 ${A.holder}" + + A.holder = "" + val p4 = A.test4() + if (p4 != 3 || A.holder != "getR4setR4:getR4setR4getR4getR4") return "fail 4: $p4 ${A.holder}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/statics/incInObject.kt b/backend.native/tests/external/codegen/blackbox/statics/incInObject.kt new file mode 100644 index 00000000000..f35b9bb83f7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/statics/incInObject.kt @@ -0,0 +1,71 @@ +object A { + private var r: Int = 1; + + fun test() : Int { + r++ + ++r + return r + } + + var holder: String = "" + + var r2: Int = 1; + get() { + holder += "getR2" + return field + } + + fun test2() : Int { + r2++ + ++r2 + return r2 + } + + var r3: Int = 1; + set(p: Int) { + holder += "setR3" + field = p + } + + fun test3() : Int { + r3++ + ++r3 + return r3 + } + + var r4: Int = 1; + get() { + holder += "getR4" + return field + } + set(p: Int) { + holder += "setR4" + field = p + } + + fun test4() : Int { + r4++ + holder += ":" + ++r4 + return r4 + } +} + +fun box() : String { + val p = A.test() + if (p != 3) return "fail 1: $p" + + val p2 = A.test2() + val holderValue = A.holder + if (p2 != 3 || holderValue != "getR2getR2getR2getR2") return "fail 2: $p2 ${holderValue}" + + A.holder = "" + val p3 = A.test3() + if (p3 != 3 || A.holder != "setR3setR3") return "fail 3: $p3 ${A.holder}" + + A.holder = "" + val p4 = A.test4() + if (p4 != 3 || A.holder != "getR4setR4:getR4setR4getR4getR4") return "fail 4: $p4 ${A.holder}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/statics/inheritedPropertyInClassObject.kt b/backend.native/tests/external/codegen/blackbox/statics/inheritedPropertyInClassObject.kt new file mode 100644 index 00000000000..2ab591a3f58 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/statics/inheritedPropertyInClassObject.kt @@ -0,0 +1,13 @@ +open class Bar(val prop: String) +class Foo { + companion object : Bar("OK") { + val p = Foo.prop + val p2 = prop + val p3 = this.prop + } + + val p4 = Foo.prop + val p5 = prop +} + +fun box(): String = Foo.prop \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/statics/inheritedPropertyInObject.kt b/backend.native/tests/external/codegen/blackbox/statics/inheritedPropertyInObject.kt new file mode 100644 index 00000000000..4d00f209f61 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/statics/inheritedPropertyInObject.kt @@ -0,0 +1,8 @@ +open class Bar(val prop: String) +object Foo : Bar("OK") { + + val p = Foo.prop + val p2 = prop + val p3 = this.prop +} +fun box(): String = Foo.prop \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/statics/inlineCallsStaticMethod.kt b/backend.native/tests/external/codegen/blackbox/statics/inlineCallsStaticMethod.kt new file mode 100644 index 00000000000..3e0b726b9ad --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/statics/inlineCallsStaticMethod.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: Test.java + +public class Test { + + protected String data = "O"; + + protected Test() { + + } + + protected static String testStatic() { + return "K"; + } + +} + +// FILE: test.kt + +public inline fun test(): String { + val p = object : Test() {} + return p.data + Test.testStatic(); +} + + +fun box(): String { + return test() +} diff --git a/backend.native/tests/external/codegen/blackbox/statics/kt8089.kt b/backend.native/tests/external/codegen/blackbox/statics/kt8089.kt new file mode 100644 index 00000000000..2fee361d80d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/statics/kt8089.kt @@ -0,0 +1,21 @@ +class C { + companion object { + private val s: String + private var s2: String + + init { + s = "O" + s2 = "O" + } + + fun foo() = s + + fun foo2() = s2 + + fun bar2() { s2 = "K" } + } +} + +fun box(): String { + return C.foo() + {C.bar2(); C.foo2()}() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/statics/protectedSamConstructor.kt b/backend.native/tests/external/codegen/blackbox/statics/protectedSamConstructor.kt new file mode 100644 index 00000000000..41be4ad28c8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/statics/protectedSamConstructor.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: JavaClass.java + +public class JavaClass { + + public String runZ(Z z) { + return z.run("O", "K"); + } + + protected interface Z { + String run(String s1, String s2); + } +} + +// FILE: Kotlin.kt + +package zzz + +import JavaClass +import JavaClass.Z + +class A : JavaClass() { + fun test() = runZ(JavaClass.Z {a, b -> a + b}) +} + +fun box(): String { + return A().test() +} diff --git a/backend.native/tests/external/codegen/blackbox/statics/protectedStatic.kt b/backend.native/tests/external/codegen/blackbox/statics/protectedStatic.kt new file mode 100644 index 00000000000..c8fe82f334d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/statics/protectedStatic.kt @@ -0,0 +1,38 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: First.java + +public abstract class First { + protected static String TEST = "OK"; + + protected static String test() { + return TEST; + } +} + +// FILE: First.kt + +package anotherPackage + +import First + +class Second : First() { + val some = { First.TEST } + fun foo() = { First.test() } + + val some2 = { TEST } + fun foo2() = { test() } +} + +fun box(): String { + if (Second().some.invoke() != "OK") return "fail 1" + + if (Second().foo().invoke() != "OK") return "fail 2" + + if (Second().some2.invoke() != "OK") return "fail 3" + + if (Second().foo2().invoke() != "OK") return "fail 4" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/statics/protectedStatic2.kt b/backend.native/tests/external/codegen/blackbox/statics/protectedStatic2.kt new file mode 100644 index 00000000000..931b1eace43 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/statics/protectedStatic2.kt @@ -0,0 +1,61 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: Base.java + +public class Base { + + protected static String BASE_ONLY = "BASE"; + + protected static String baseOnly() { + return BASE_ONLY; + } + + protected static String TEST = "BASE"; + + protected static String test() { + return TEST; + } + + public static class Derived extends Base { + protected static String TEST = "DERIVED"; + + protected static String test() { + return TEST; + } + } +} + +// FILE: Kotlin.kt + +package anotherPackage + +import Base.Derived +import Base + +class Kotlin : Base.Derived() { + fun doTest(): String { + + if ({ TEST }() != "DERIVED") return "fail 1" + if ({ test() }() != "DERIVED") return "fail 2" + + if ({ Derived.TEST }() != "DERIVED") return "fail 3" + if ({ Derived.test() }() != "DERIVED") return "fail 4" + + if ({ Base.TEST }() != "BASE") return "fail 5" + if ({ Base.test() }() != "BASE") return "fail 6" + + + if ({ Base.BASE_ONLY }() != "BASE") return "fail 7" + if ({ Base.baseOnly() }() != "BASE") return "fail 8" + + if ({ BASE_ONLY }() != "BASE") return "fail 9" + if ({ baseOnly() }() != "BASE") return "fail 10" + + return "OK" + } +} + +fun box(): String { + return Kotlin().doTest() +} diff --git a/backend.native/tests/external/codegen/blackbox/statics/protectedStaticAndInline.kt b/backend.native/tests/external/codegen/blackbox/statics/protectedStaticAndInline.kt new file mode 100644 index 00000000000..738e874d2e4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/statics/protectedStaticAndInline.kt @@ -0,0 +1,29 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: First.java + +public abstract class First { + protected static String TEST = "O"; + + protected static String test() { + return "K"; + } +} + +// FILE: Kotlin.kt + +package anotherPackage + +import First + +class Test : First() { + + inline fun doTest(): String { + return TEST + test() + } +} + +fun box(): String { + return Test().doTest() +} diff --git a/backend.native/tests/external/codegen/blackbox/statics/syntheticAccessor.kt b/backend.native/tests/external/codegen/blackbox/statics/syntheticAccessor.kt new file mode 100644 index 00000000000..2a390400701 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/statics/syntheticAccessor.kt @@ -0,0 +1,12 @@ +object A { + private val p = "OK"; + + object B { + val z = p; + } + +} + +fun box(): String { + return A.B.z +} diff --git a/backend.native/tests/external/codegen/blackbox/storeStackBeforeInline/differentTypes.kt b/backend.native/tests/external/codegen/blackbox/storeStackBeforeInline/differentTypes.kt new file mode 100644 index 00000000000..2d38eb00026 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/storeStackBeforeInline/differentTypes.kt @@ -0,0 +1,16 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun bar(x: Int, y: Long, z: Byte, s: String) = x.toString() + y.toString() + z.toString() + s + +fun foobar(x: Int, y: Long, s: String, z: Byte) = x.toString() + y.toString() + s + z.toString() + +fun foo() : String { + return foobar(1, 2L, bar(3, 4L, 5.toByte(), "6"), 7.toByte()) +} + +fun box() : String { + assertEquals("1234567", foo()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/storeStackBeforeInline/primitiveMerge.kt b/backend.native/tests/external/codegen/blackbox/storeStackBeforeInline/primitiveMerge.kt new file mode 100644 index 00000000000..7a0c44138c9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/storeStackBeforeInline/primitiveMerge.kt @@ -0,0 +1,18 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun bar() : Boolean = true + +fun foobar1(x: Boolean, y: String, z: String) = x.toString() + y + z +fun foobar2(x: Any, y: String, z: String) = x.toString() + y + z + +inline fun foo() = "-" + +fun box(): String { + val result1 = foobar1(if (1 == 1) true else bar(), foo(), "OK") + val result2 = foobar2(if (1 == 1) "true" else arrayOf("false"), foo(), "OK") + assertEquals("true-OK", result1) + assertEquals("true-OK", result2) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/storeStackBeforeInline/simple.kt b/backend.native/tests/external/codegen/blackbox/storeStackBeforeInline/simple.kt new file mode 100644 index 00000000000..02c77ef3f87 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/storeStackBeforeInline/simple.kt @@ -0,0 +1,18 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun bar(x: Int) : Int { + return x +} + +fun foobar(x: Int, y: Int, z: Int) = x + y + z + +fun foo() : Int { + return foobar(1, bar(2), 3) +} + +fun box() : String { + assertEquals(6, foo()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/storeStackBeforeInline/unreachableMarker.kt b/backend.native/tests/external/codegen/blackbox/storeStackBeforeInline/unreachableMarker.kt new file mode 100644 index 00000000000..303293d3cd8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/storeStackBeforeInline/unreachableMarker.kt @@ -0,0 +1,26 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun bar(block: () -> String) : String { + return block() +} + +inline fun bar2() : String { + return bar { return "def" } +} + +fun foobar(x: String, y: String, z: String) = x + y + z + +fun foo() : String { + return foobar( + "abc", + bar2(), + "ghi" + ) +} + +fun box() : String { + assertEquals("abcdefghi", foo()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/storeStackBeforeInline/withLambda.kt b/backend.native/tests/external/codegen/blackbox/storeStackBeforeInline/withLambda.kt new file mode 100644 index 00000000000..44e64d5a9bc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/storeStackBeforeInline/withLambda.kt @@ -0,0 +1,15 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +inline fun bar(x: String, block: (String) -> String) = "def" + block(x) +fun foobar(x: String, y: String, z: String) = x + y + z + +fun foo() : String { + return foobar("abc", bar("ghi") { x -> x + "jkl" }, "mno") +} + +fun box() : String { + assertEquals("abcdefghijklmno", foo()) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/strings/ea35743.kt b/backend.native/tests/external/codegen/blackbox/strings/ea35743.kt new file mode 100644 index 00000000000..31b59f2dcbb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/strings/ea35743.kt @@ -0,0 +1,6 @@ +val Int.test: String get() = "test" + +fun box(): String { + val x = "a ${1.test}" + return if (x == "a test") "OK" else "Fail $x" +} diff --git a/backend.native/tests/external/codegen/blackbox/strings/forInString.kt b/backend.native/tests/external/codegen/blackbox/strings/forInString.kt new file mode 100644 index 00000000000..f5bcbbde7be --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/strings/forInString.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME + +fun foo(): Int { + var sum = 0 + for (c in "239") + sum += (c.toInt() - '0'.toInt()) + return sum +} + +fun box(): String { + val f = foo() + return if (f == 14) "OK" else "Fail $f" +} diff --git a/backend.native/tests/external/codegen/blackbox/strings/interpolation.kt b/backend.native/tests/external/codegen/blackbox/strings/interpolation.kt new file mode 100644 index 00000000000..772cb33771a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/strings/interpolation.kt @@ -0,0 +1,9 @@ +fun test(p: String?): String { + return "${p ?: "Default"} test" +} +fun box(): String { + if (test(null) != "Default test") return "fail 1: ${test(null)}" + if (test("Good") != "Good test") return "fail 1: ${test("OK")}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/strings/kt2592.kt b/backend.native/tests/external/codegen/blackbox/strings/kt2592.kt new file mode 100644 index 00000000000..589d5ab8586 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/strings/kt2592.kt @@ -0,0 +1,7 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun box(): String { + String() + return String() + "OK" + String() +} diff --git a/backend.native/tests/external/codegen/blackbox/strings/kt3571.kt b/backend.native/tests/external/codegen/blackbox/strings/kt3571.kt new file mode 100644 index 00000000000..960a37656a0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/strings/kt3571.kt @@ -0,0 +1,6 @@ +class Thing(delegate: CharSequence) : CharSequence by delegate + +fun box(): String { + val l = Thing("hello there").length + return if (l == 11) "OK" else "Fail $l" +} diff --git a/backend.native/tests/external/codegen/blackbox/strings/kt3652.kt b/backend.native/tests/external/codegen/blackbox/strings/kt3652.kt new file mode 100644 index 00000000000..f9e678089b8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/strings/kt3652.kt @@ -0,0 +1,9 @@ +fun box(): String { + var a = 'a' + + if ("${a++}x" != "ax") return "fail1" + + if ("${a++}" != "b") return "fail2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/strings/kt5389_stringBuilderGet.kt b/backend.native/tests/external/codegen/blackbox/strings/kt5389_stringBuilderGet.kt new file mode 100644 index 00000000000..c6547b517a4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/strings/kt5389_stringBuilderGet.kt @@ -0,0 +1,4 @@ +fun box(): String { + val sb = StringBuilder("OK") + return "${sb.get(0)}${sb[1]}" +} diff --git a/backend.native/tests/external/codegen/blackbox/strings/kt5956.kt b/backend.native/tests/external/codegen/blackbox/strings/kt5956.kt new file mode 100644 index 00000000000..037ee9ac1dc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/strings/kt5956.kt @@ -0,0 +1,15 @@ +// KT-5956 java.lang.AbstractMethodError: test.Thing.subSequence(II)Ljava/lang/CharSequence + +class Thing(val delegate: CharSequence) : CharSequence { + override fun get(index: Int): Char { + throw UnsupportedOperationException() + } + override val length: Int get() = 0 + override fun subSequence(start: Int, end: Int) = delegate.subSequence(start, end) +} + +fun box(): String { + val txt = Thing("hello there") + val s = txt.subSequence(0, 1) + return if ("$s" == "h") "OK" else "Fail: $s" +} diff --git a/backend.native/tests/external/codegen/blackbox/strings/kt881.kt b/backend.native/tests/external/codegen/blackbox/strings/kt881.kt new file mode 100644 index 00000000000..ba9911d887e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/strings/kt881.kt @@ -0,0 +1,6 @@ +fun box() : String { + val b = 1+1 + if ("$b" != "2") return "fail" + if ("${1+1}" != "2") return "fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/strings/kt889.kt b/backend.native/tests/external/codegen/blackbox/strings/kt889.kt new file mode 100644 index 00000000000..c09089eefec --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/strings/kt889.kt @@ -0,0 +1,12 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +operator fun Int.plus(s: String) : String { + System.out?.println("Int.plus(s: String) called") + return s +} + +fun box() : String { + val s = "${1 + "a"}" + return if(s == "a") "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/strings/kt894.kt b/backend.native/tests/external/codegen/blackbox/strings/kt894.kt new file mode 100644 index 00000000000..f8e9620a8fc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/strings/kt894.kt @@ -0,0 +1,11 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun stringConcat(n : Int) : String? { + var string : String? = "" + for (i in 0..(n - 1)) + string += "LOL " + return string +} + +fun box() = if(stringConcat(3) == "LOL LOL LOL ") "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/strings/multilineStringsWithTemplates.kt b/backend.native/tests/external/codegen/blackbox/strings/multilineStringsWithTemplates.kt new file mode 100644 index 00000000000..38e661755cd --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/strings/multilineStringsWithTemplates.kt @@ -0,0 +1,31 @@ +fun box() : String { + val s = "abc" + val test1 = """$s""" + if (test1 != "abc") return "Fail 1: $test1" + + val test2 = """${s}""" + if (test2 != "abc") return "Fail 2: $test2" + + val test3 = """ "$s" """ + if (test3 != " \"abc\" ") return "Fail 3: $test3" + + val test4 = """ "${s}" """ + if (test4 != " \"abc\" ") return "Fail 4: $test4" + + val test5 = +""" + ${s.length} +""" + if (test5 != "\n 3\n") return "Fail 5: $test5" + + val test6 = """\n""" + if (test6 != "\\n") return "Fail 6: $test6" + + val test7 = """\${'$'}foo""" + if (test7 != "\\\$foo") return "Fail 7: $test7" + + val test8 = """$ foo""" + if (test8 != "$ foo") return "Fail 8: $test8" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/strings/rawStrings.kt b/backend.native/tests/external/codegen/blackbox/strings/rawStrings.kt new file mode 100644 index 00000000000..caa5b8fc27a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/strings/rawStrings.kt @@ -0,0 +1,6 @@ +fun box() : String { + val s = """ foo \n bar """ + if (s != " foo \\n bar ") return "Fail: '$s'" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/strings/rawStringsWithManyQuotes.kt b/backend.native/tests/external/codegen/blackbox/strings/rawStringsWithManyQuotes.kt new file mode 100644 index 00000000000..1fb97bd718e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/strings/rawStringsWithManyQuotes.kt @@ -0,0 +1,28 @@ +class P(val actual: String, val expected: String) +fun array(vararg s: P) = s + +fun box() : String { + val data = array( + P("""""", ""), + P(""""""", "\""), + P("""""""", "\"\""), + P(""""""""", "\"\"\""), + P("""""""""", "\"\"\"\""), + P("""" """, "\" "), + P(""""" """, "\"\" "), + P(""" """", " \""), + P(""" """"", " \"\""), + P(""" """""", " \"\"\""), + P(""" """"""", " \"\"\"\""), + P(""" """""""", " \"\"\"\"\""), + P("""" """", "\" \""), + P(""""" """"", "\"\" \"\"") + ) + + for (i in 0..data.size-1) { + val p = data[i] + if (p.actual != p.expected) return "Fail at #$i. actual='${p.actual}', expected='${p.expected}'" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/strings/stringBuilderAppend.kt b/backend.native/tests/external/codegen/blackbox/strings/stringBuilderAppend.kt new file mode 100644 index 00000000000..e11087ddfd5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/strings/stringBuilderAppend.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +class A() { + + override fun toString(): String { + return "A" + } +} + +fun box() : String { + + val s = "1" + "2" + 3 + 4L + 5.0 + 6F + '7' + A() + + if (s != "12345.06.07A") return "fail $s" + + return "OK" +} + diff --git a/backend.native/tests/external/codegen/blackbox/strings/stringPlusOnlyWorksOnString.kt b/backend.native/tests/external/codegen/blackbox/strings/stringPlusOnlyWorksOnString.kt new file mode 100644 index 00000000000..cf713b647c2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/strings/stringPlusOnlyWorksOnString.kt @@ -0,0 +1,7 @@ +// WITH_RUNTIME + +fun box(): String { + var x: MutableCollection = ArrayList() + x + ArrayList() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/super/basicmethodSuperClass.kt b/backend.native/tests/external/codegen/blackbox/super/basicmethodSuperClass.kt new file mode 100644 index 00000000000..612cee4e58b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/basicmethodSuperClass.kt @@ -0,0 +1,15 @@ +class N() : ArrayList() { + override fun add(el: Any) : Boolean { + if (!super.add(el)) { + throw Exception() + } + return false + } +} + +fun box(): String { + val n = N() + if (n.add("239")) return "fail" + if (n.get(0) == "239") return "OK"; + return "fail"; +} diff --git a/backend.native/tests/external/codegen/blackbox/super/basicmethodSuperTrait.kt b/backend.native/tests/external/codegen/blackbox/super/basicmethodSuperTrait.kt new file mode 100644 index 00000000000..886987cf6f3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/basicmethodSuperTrait.kt @@ -0,0 +1,14 @@ + +interface Tr { + fun extra() : String = "_" +} + +class N() : Tr { + override fun extra() : String = super.extra() + super.extra() +} + +fun box(): String { + val n = N() + if (n.extra() == "__") return "OK" + return "fail"; +} diff --git a/backend.native/tests/external/codegen/blackbox/super/basicproperty.kt b/backend.native/tests/external/codegen/blackbox/super/basicproperty.kt new file mode 100644 index 00000000000..f1fab6ffe23 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/basicproperty.kt @@ -0,0 +1,24 @@ +open class M() { + open var b: Int = 0 +} + +class N() : M() { + val a : Int + get() { + super.b = super.b + 1 + return super.b + 1 + } + override var b: Int = a + 1 + + val superb : Int + get() = super.b +} + +fun box(): String { + val n = N() + n.a + n.b + n.superb + if (n.b == 3 && n.a == 4 && n.superb == 3) return "OK"; + return "fail"; +} diff --git a/backend.native/tests/external/codegen/blackbox/super/enclosedFun.kt b/backend.native/tests/external/codegen/blackbox/super/enclosedFun.kt new file mode 100644 index 00000000000..5f317b46f77 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/enclosedFun.kt @@ -0,0 +1,31 @@ +interface BK { + fun x() : Int = 50 +} + +interface K : BK { + override fun x() : Int = super.x() * 2 +} + +open class M() { + open fun x() : Int = 10 +} + +open class N() : M(), K { + + override fun x() : Int = 20 + + open inner class C() : K { + fun test1() = x() + fun test2() = super@N.x() + fun test3() = super@N.x() + fun test4() = super.x() + } +} + +fun box(): String { + if (N().C().test1() != 100) return "test1 fail"; + if (N().C().test2() != 10) return "test2 fail"; + if (N().C().test3() != 100) return "test3 fail"; + if (N().C().test4() != 100) return "test4 fail"; + return "OK"; +} diff --git a/backend.native/tests/external/codegen/blackbox/super/enclosedVar.kt b/backend.native/tests/external/codegen/blackbox/super/enclosedVar.kt new file mode 100644 index 00000000000..50477570820 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/enclosedVar.kt @@ -0,0 +1,22 @@ +open class M() { + open var y = 500 +} + +open class N() : M() { + + override var y = 200 + + open inner class C() { + fun test5() = y + fun test6() : Int { + super@N.y += 200 + return super@N.y + } + } +} + +fun box(): String { + if (N().C().test5() != 200) return "test5 fail"; + if (N().C().test6() != 700) return "test6 fail"; + return "OK"; +} diff --git a/backend.native/tests/external/codegen/blackbox/super/innerClassLabeledSuper.kt b/backend.native/tests/external/codegen/blackbox/super/innerClassLabeledSuper.kt new file mode 100644 index 00000000000..cbb0a875df9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/innerClassLabeledSuper.kt @@ -0,0 +1,38 @@ +interface BK { + fun foo(): String + fun bar(): String +} + +interface K : BK { + override fun foo() = bar() +} + +class A : K { + override fun foo() = "A.foo" + override fun bar() = "A.bar" + + inner class B : K { + override fun foo() = "B.foo" + override fun bar() = "B.bar" + + fun test1() = super@A.foo() + fun test2() = super@B.foo() + fun test3() = super.foo() + fun test4() = super@A.foo() + fun test5() = super@B.foo() + fun test6() = super.foo() + } +} + + +fun box(): String { + val b = A().B() + if (b.test1() != "A.bar") return "test1 ${b.test1()}" + if (b.test2() != "B.bar") return "test2 ${b.test2()}" + if (b.test3() != "B.bar") return "test3 ${b.test3()}" + if (b.test4() != "A.bar") return "test4 ${b.test4()}" + if (b.test5() != "B.bar") return "test5 ${b.test5()}" + if (b.test6() != "B.bar") return "test6 ${b.test6()}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/super/innerClassLabeledSuper2.kt b/backend.native/tests/external/codegen/blackbox/super/innerClassLabeledSuper2.kt new file mode 100644 index 00000000000..1a0bca8c437 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/innerClassLabeledSuper2.kt @@ -0,0 +1,44 @@ +//inspired by kt3492 +interface BK { + fun foo(): String + fun bar(): String +} + +interface KTrait: BK { + override fun foo() = bar() +} + +open abstract class K : KTrait { + +} + +class A : K() { + override fun foo() = "A.foo" + override fun bar() = "A.bar" + + inner class B : K() { + override fun foo() = "B.foo" + override fun bar() = "B.bar" + + fun test1() = super@A.foo() + fun test2() = super@B.foo() + fun test3() = super.foo() + fun test4() = super@A.foo() + fun test5() = super@B.foo() + fun test6() = super.foo() + } +} + + +fun box(): String { + val b = A().B() + if (b.test1() != "A.bar") return "test1 ${b.test1()}" + if (b.test2() != "B.bar") return "test2 ${b.test2()}" + if (b.test3() != "B.bar") return "test3 ${b.test3()}" + if (b.test4() != "A.bar") return "test4 ${b.test4()}" + if (b.test5() != "B.bar") return "test5 ${b.test5()}" + if (b.test6() != "B.bar") return "test6 ${b.test6()}" + + return "OK" +} + diff --git a/backend.native/tests/external/codegen/blackbox/super/innerClassLabeledSuperProperty.kt b/backend.native/tests/external/codegen/blackbox/super/innerClassLabeledSuperProperty.kt new file mode 100644 index 00000000000..bb8098564f6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/innerClassLabeledSuperProperty.kt @@ -0,0 +1,38 @@ +interface Base { + val foo: String + fun bar(): String +} + +abstract class K : Base { + override val foo = bar() +} + +class A : K() { + override val foo = "A.foo" + override fun bar() = "A.bar" + + inner class B : K() { + override val foo = "B.foo" + override fun bar() = "B.bar" + + fun test1() = super@A.foo + fun test2() = super@B.foo + fun test3() = super.foo + fun test4() = super@A.foo + fun test5() = super@B.foo + fun test6() = super.foo + } +} + + +fun box(): String { + val b = A().B() + if (b.test1() != "A.bar") return "test1 ${b.test1()}" + if (b.test2() != "B.bar") return "test2 ${b.test2()}" + if (b.test3() != "B.bar") return "test3 ${b.test3()}" + if (b.test4() != "A.bar") return "test4 ${b.test4()}" + if (b.test5() != "B.bar") return "test5 ${b.test5()}" + if (b.test6() != "B.bar") return "test6 ${b.test6()}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/super/innerClassLabeledSuperProperty2.kt b/backend.native/tests/external/codegen/blackbox/super/innerClassLabeledSuperProperty2.kt new file mode 100644 index 00000000000..effc71e7925 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/innerClassLabeledSuperProperty2.kt @@ -0,0 +1,43 @@ +//inspired by kt3492 +interface Base { + val foo: String + fun bar(): String +} + +abstract class KWithOverride : Base { + override val foo = bar() +} + +abstract class K : KWithOverride() { + +} + +class A : K() { + override val foo = "A.foo" + override fun bar() = "A.bar" + + inner class B : K() { + override val foo = "B.foo" + override fun bar() = "B.bar" + + fun test1() = super@A.foo + fun test2() = super@B.foo + fun test3() = super.foo + fun test4() = super@A.foo + fun test5() = super@B.foo + fun test6() = super.foo + } +} + + +fun box(): String { + val b = A().B() + if (b.test1() != "A.bar") return "test1 ${b.test1()}" + if (b.test2() != "B.bar") return "test2 ${b.test2()}" + if (b.test3() != "B.bar") return "test3 ${b.test3()}" + if (b.test4() != "A.bar") return "test4 ${b.test4()}" + if (b.test5() != "B.bar") return "test5 ${b.test5()}" + if (b.test6() != "B.bar") return "test6 ${b.test6()}" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/super/innerClassQualifiedFunctionCall.kt b/backend.native/tests/external/codegen/blackbox/super/innerClassQualifiedFunctionCall.kt new file mode 100644 index 00000000000..557905cedbe --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/innerClassQualifiedFunctionCall.kt @@ -0,0 +1,46 @@ +interface T { + open fun baz(): String = "T.baz" +} + +open class A { + open val foo: String = "OK" + open fun bar(): String = "OK" + open fun boo(): String = "OK" +} + +open class B : A(), T { + override fun bar(): String = "B" + override fun baz(): String = "B.baz" + inner class E { + val foo: String = super@B.foo + fun bar() = super@B.bar() + super@B.bar() + super@B.baz() + } +} + +class C : B() { + override fun bar(): String = "C" + override fun boo(): String = "C" + inner class D { + val foo: String = super@C.foo + fun bar() = super@C.bar() + super@C.boo() + } +} + +fun box(): String { + var r = "" + + r = B().E().foo + if (r != "OK") return "fail 1; r = $r" + r = "" + r = B().E().bar() + if (r != "OKOKT.baz") return "fail 2; r = $r" + + r = "" + r = C().D().foo + if (r != "OK") return "fail 3; r = $r" + r = "" + r = C().D().bar() + if (r != "BOK") return "fail 4; r = $r" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/super/innerClassQualifiedPropertyAccess.kt b/backend.native/tests/external/codegen/blackbox/super/innerClassQualifiedPropertyAccess.kt new file mode 100644 index 00000000000..bdcd70ce962 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/innerClassQualifiedPropertyAccess.kt @@ -0,0 +1,45 @@ +interface T { + open val baz: String + get() = "T.baz" +} + +open class A { + open val bar: String + get() = "OK" + open val boo: String + get() = "OK" +} + +open class B : A(), T { + override val bar: String + get() = "B" + override val baz: String + get() = "B.baz" + inner class E { + val bar: String + get() = super@B.bar + super@B.bar + super@B.baz + } +} + +class C : B() { + override val bar: String + get() = "C" + override val boo: String + get() = "C" + inner class D { + val bar: String + get() = super@C.bar + super@C.boo + } +} + +fun box(): String { + var r = "" + + r = B().E().bar + if (r != "OKOKT.baz") return "fail 1; r = $r" + + r = C().D().bar + if (r != "BOK") return "fail 2; r = $r" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/super/kt14243.kt b/backend.native/tests/external/codegen/blackbox/super/kt14243.kt new file mode 100644 index 00000000000..75d5fcb7ae7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/kt14243.kt @@ -0,0 +1,18 @@ +interface Z { + fun test(p: T): T { + return p + } +} + +open class ZImpl : Z + +class ZImpl2 : ZImpl() { + + override fun test(p: String): String { + return super.test(p) + } +} + +fun box(): String { + return ZImpl2().test("OK") +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/super/kt14243_2.kt b/backend.native/tests/external/codegen/blackbox/super/kt14243_2.kt new file mode 100644 index 00000000000..b72bf3dac7c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/kt14243_2.kt @@ -0,0 +1,20 @@ +interface Z { + fun test(p: T): T { + return p + } +} + +open class ZImpl : Z + +open class ZImpl2 : Z, ZImpl() + +class ZImpl3 : ZImpl2() { + + override fun test(p: String): String { + return super.test(p) + } +} + +fun box(): String { + return ZImpl3().test("OK") +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/super/kt14243_class.kt b/backend.native/tests/external/codegen/blackbox/super/kt14243_class.kt new file mode 100644 index 00000000000..c0ec94be493 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/kt14243_class.kt @@ -0,0 +1,20 @@ + +open class Z { + open fun test(p: T, z: Y): T { + return p + } +} + +open class ZImpl : Z() + +open class ZImpl2 : ZImpl() + +class ZImpl3 : ZImpl2() { + override fun test(p: String, z: String): String { + return super.test(p, z) + } +} + +fun box(): String { + return ZImpl3().test("OK", "fail") +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/super/kt14243_prop.kt b/backend.native/tests/external/codegen/blackbox/super/kt14243_prop.kt new file mode 100644 index 00000000000..73979c08226 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/kt14243_prop.kt @@ -0,0 +1,21 @@ +interface Z { + val value: T + + val z: T + get() = value +} + +open class ZImpl : Z { + override val value: String + get() = "OK" +} + +open class ZImpl2 : ZImpl() { + override val z: String + get() = super.z +} + + +fun box(): String { + return ZImpl2().value +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/super/kt3492ClassFun.kt b/backend.native/tests/external/codegen/blackbox/super/kt3492ClassFun.kt new file mode 100644 index 00000000000..1dd8d1b2770 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/kt3492ClassFun.kt @@ -0,0 +1,19 @@ +open class A { + open fun foo2(): String = "OK" +} + +open class B : A() { + +} + +class C : B() { + inner class D { + val foo: String = super@C.foo2() + } +} + +fun box() : String { + val obj = C().D(); + return obj.foo +} + diff --git a/backend.native/tests/external/codegen/blackbox/super/kt3492ClassProperty.kt b/backend.native/tests/external/codegen/blackbox/super/kt3492ClassProperty.kt new file mode 100644 index 00000000000..25feedb525f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/kt3492ClassProperty.kt @@ -0,0 +1,15 @@ +open class A { + open val foo: String = "OK" +} + +open class B : A() { + +} + +class C : B() { + inner class D { + val foo: String = super@C.foo + } +} + +fun box() = C().D().foo diff --git a/backend.native/tests/external/codegen/blackbox/super/kt3492TraitFun.kt b/backend.native/tests/external/codegen/blackbox/super/kt3492TraitFun.kt new file mode 100644 index 00000000000..144e86036a3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/kt3492TraitFun.kt @@ -0,0 +1,19 @@ +interface ATrait { + open fun foo2(): String = "OK" +} + +open class B : ATrait { + +} + +class C : B() { + inner class D { + val foo: String = super@C.foo2() + } +} + +fun box() : String { + val obj = C().D(); + return obj.foo +} + diff --git a/backend.native/tests/external/codegen/blackbox/super/kt3492TraitProperty.kt b/backend.native/tests/external/codegen/blackbox/super/kt3492TraitProperty.kt new file mode 100644 index 00000000000..c4c3298afcb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/kt3492TraitProperty.kt @@ -0,0 +1,16 @@ +interface A { + open val foo: String + get() = "OK" +} + +open class B : A { + +} + +class C : B() { + inner class D { + val foo: String = super@C.foo + } +} + +fun box() = C().D().foo diff --git a/backend.native/tests/external/codegen/blackbox/super/kt4173.kt b/backend.native/tests/external/codegen/blackbox/super/kt4173.kt new file mode 100644 index 00000000000..12ca4f5c6ee --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/kt4173.kt @@ -0,0 +1,18 @@ +open class C(val f: () -> Unit) { + fun test() { + f() + } +} + +class B(var x: Int) { + fun foo() { + object : C({x = 3}) {}.test() + } +} + + +fun box() : String { + val b = B(1) + b.foo() + return if (b.x != 3) "fail: b.x = ${b.x}" else "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/super/kt4173_2.kt b/backend.native/tests/external/codegen/blackbox/super/kt4173_2.kt new file mode 100644 index 00000000000..3bc81264f0c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/kt4173_2.kt @@ -0,0 +1,20 @@ +open class X(var s: ()-> Unit) + +open class C(val f: X) { + fun test() { + f.s() + } +} + +class B(var x: Int) { + fun foo() { + object : C(object: X({x = 3}) {}) {}.test() + } +} + + +fun box() : String { + val b = B(1) + b.foo() + return if (b.x != 3) "fail: b.x = ${b.x}" else "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/super/kt4173_3.kt b/backend.native/tests/external/codegen/blackbox/super/kt4173_3.kt new file mode 100644 index 00000000000..8c23cf83f28 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/kt4173_3.kt @@ -0,0 +1,27 @@ +open class C(s: Int) { + fun test() { + + } +} + +class B(var x: Int) { + fun foo() { + class A(val a: Int) : C({a}()) { + + } + A(11).test() + + + class B(val a: Int) : C(a) { + } + + B(11).test() + } +} + + +fun box() : String { + val b = B(1) + b.foo() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/super/kt4982.kt b/backend.native/tests/external/codegen/blackbox/super/kt4982.kt new file mode 100644 index 00000000000..8c01d8f2212 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/kt4982.kt @@ -0,0 +1,21 @@ +abstract class WaitFor { + init { + condition() + } + + abstract fun condition() : Boolean; +} + +fun box(): String { + val local = "" + var result = "fail" + val s = object: WaitFor() { + + override fun condition(): Boolean { + result = "OK" + return result.length== 2 + } + } + + return result; +} diff --git a/backend.native/tests/external/codegen/blackbox/super/multipleSuperTraits.kt b/backend.native/tests/external/codegen/blackbox/super/multipleSuperTraits.kt new file mode 100644 index 00000000000..2ddb25d35b9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/multipleSuperTraits.kt @@ -0,0 +1,13 @@ +interface T1 { + fun foo() = "O" +} + +interface T2 { + fun foo() = "K" +} + +class A : T1, T2 { + override fun foo() = super.foo() + super.foo() +} + +fun box() = A().foo() diff --git a/backend.native/tests/external/codegen/blackbox/super/traitproperty.kt b/backend.native/tests/external/codegen/blackbox/super/traitproperty.kt new file mode 100644 index 00000000000..a5de71c24eb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/traitproperty.kt @@ -0,0 +1,31 @@ +interface M { + var backingB : Int + var b : Int + get() = backingB + set(value: Int) { + backingB = value + } +} + +class N() : M { + public override var backingB : Int = 0 + + val a : Int + get() { + super.b = super.b + 1 + return super.b + 1 + } + override var b: Int = a + 1 + + val superb : Int + get() = super.b +} + +fun box(): String { + val n = N() + n.a + n.b + n.superb + if (n.b == 3 && n.a == 4 && n.superb == 3) return "OK"; + return "fail"; +} diff --git a/backend.native/tests/external/codegen/blackbox/super/unqualifiedSuper.kt b/backend.native/tests/external/codegen/blackbox/super/unqualifiedSuper.kt new file mode 100644 index 00000000000..9863671fa68 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/unqualifiedSuper.kt @@ -0,0 +1,66 @@ +open class Base() { + open fun baseFun(): String = "Base.baseFun()" + + open fun unambiguous(): String = "Base.unambiguous()" + + open val baseProp: String + get() = "Base.baseProp" +} + +interface Interface { + fun interfaceFun(): String = "Interface.interfaceFun()" + + fun unambiguous(): String // NB abstract +} + +interface AnotherInterface + +interface DerivedInterface: Interface, AnotherInterface { + override fun interfaceFun(): String = "DerivedInterface.interfaceFun()" + + override fun unambiguous(): String = "DerivedInterface.unambiguous()" + + fun callsFunFromSuperInterface(): String = super.interfaceFun() +} + +class Derived : Base(), Interface { + override fun baseFun(): String = "Derived.baseFun()" + + override fun unambiguous(): String = "Derived.unambiguous()" + + override fun interfaceFun(): String = "Derived.interfaceFun()" + + override val baseProp: String + get() = "Derived.baseProp" + + fun callsBaseFun(): String = super.baseFun() + + fun callsUnambiguousFun(): String = super.unambiguous() + + fun getsBaseProp(): String = super.baseProp + + fun callsInterfaceFun(): String = super.interfaceFun() +} + +fun box(): String { + val d = Derived() + + val test1 = d.callsBaseFun() + if (test1 != "Base.baseFun()") return "Failed: d.callsBaseFun()==$test1" + + val test2 = d.callsUnambiguousFun() + if (test2 != "Base.unambiguous()") return "Failed: d.callsUnambiguousFun()==$test2" + + val test3 = d.getsBaseProp() + if (test3 != "Base.baseProp") return "Failed: d.getsBaseProp()==$test3" + + val test4 = d.callsInterfaceFun() + if (test4 != "Interface.interfaceFun()") return "Failed: d.callsInterfaceFun()==$test4" + + val di = object : DerivedInterface {} + + val test5 = di.callsFunFromSuperInterface() + if (test5 != "Interface.interfaceFun()") return "Failed: di.callsFunFromSuperInterface()==$test5" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/super/unqualifiedSuperWithDeeperHierarchies.kt b/backend.native/tests/external/codegen/blackbox/super/unqualifiedSuperWithDeeperHierarchies.kt new file mode 100644 index 00000000000..c9ab55a897d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/unqualifiedSuperWithDeeperHierarchies.kt @@ -0,0 +1,63 @@ +open class DeeperBase { + open fun deeperBaseFun(): String = "DeeperBase.deeperBaseFun()" + + open val deeperBaseProp: String + get() = "DeeperBase.deeperBaseProp" +} + +open class DeepBase : DeeperBase() { +} + +interface DeeperInterface { + fun deeperInterfaceFun(): String = "DeeperInterface.deeperInterfaceFun()" + + val deeperInterfaceProp: String + get() = "DeeperInterface.deeperInterfaceProp" +} + +interface DeepInterface : DeeperInterface { + fun deepInterfaceFun(): String = "DeepInterface.deepInterfaceFun()" +} + +class DeepDerived : DeepBase(), DeepInterface { + override fun deeperBaseFun(): String = "DeepDerived.deeperBaseFun()" + + override val deeperBaseProp: String + get() = "DeepDerived.deeperBaseProp" + + override fun deeperInterfaceFun(): String = "DeepDerived.deeperInterfaceFun()" + + override val deeperInterfaceProp: String + get() = "DeepDerived.deeperInterfaceProp" + + override fun deepInterfaceFun(): String = "DeepDerived.deepInterfaceFun()" + + fun callsSuperDeeperBaseFun(): String = super.deeperBaseFun() + + fun getsSuperDeeperBaseProp(): String = super.deeperBaseProp + + fun callsSuperDeepInterfaceFun(): String = super.deepInterfaceFun() + fun callsSuperDeeperInterfaceFun(): String = super.deeperInterfaceFun() + fun getsSuperDeeperInterfaceProp(): String = super.deeperInterfaceProp +} + +fun box(): String { + val dd = DeepDerived() + + val test1 = dd.callsSuperDeeperBaseFun() + if (test1 != "DeeperBase.deeperBaseFun()") return "Failed: dd.callsSuperDeeperBaseFun()==$test1" + + val test2 = dd.getsSuperDeeperBaseProp() + if (test2 != "DeeperBase.deeperBaseProp") return "Failed: dd.getsSuperDeeperBaseProp()==$test2" + + val test3 = dd.callsSuperDeepInterfaceFun() + if (test3 != "DeepInterface.deepInterfaceFun()") return "Failed: dd.callsSuperDeepInterfaceFun()==$test3" + + val test4 = dd.callsSuperDeeperInterfaceFun() + if (test4 != "DeeperInterface.deeperInterfaceFun()") return "Failed: dd.callsSuperDeeperInterfaceFun()==$test4" + + val test5 = dd.getsSuperDeeperInterfaceProp() + if (test5 != "DeeperInterface.deeperInterfaceProp") return "Failed: dd.getsSuperDeeperInterfaceProp()==$test5" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/super/unqualifiedSuperWithMethodsOfAny.kt b/backend.native/tests/external/codegen/blackbox/super/unqualifiedSuperWithMethodsOfAny.kt new file mode 100644 index 00000000000..b0eb1ec0d01 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/super/unqualifiedSuperWithMethodsOfAny.kt @@ -0,0 +1,25 @@ +interface ISomething + +open class ClassWithToString { + override fun toString(): String = "C" +} + +interface IWithToString { + override fun toString(): String +} + +class C1 : ClassWithToString(), ISomething { + override fun toString(): String = super.toString() +} + +class C2 : ClassWithToString(), IWithToString, ISomething { + override fun toString(): String = super.toString() +} + +fun box(): String { + return when { + C1().toString() != "C" -> "Failed #1" + C2().toString() != "C" -> "Failed #2" + else -> "OK" + } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/synchronized/changeMonitor.kt b/backend.native/tests/external/codegen/blackbox/synchronized/changeMonitor.kt new file mode 100644 index 00000000000..effbf887c33 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/synchronized/changeMonitor.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +fun box(): String { + var obj0 = "0" as java.lang.Object + var obj1 = "1" as java.lang.Object + + var v = obj0 + synchronized (v) { + v = obj1 + } + assertThatThreadDoesNotOwnMonitor(obj0) + + return "OK" +} + +fun assertThatThreadDoesNotOwnMonitor(obj: java.lang.Object) { + try { + obj.wait(1) + throw IllegalStateException("Not owning a monitor!") + } + catch (e: IllegalMonitorStateException) { + // OK + } +} diff --git a/backend.native/tests/external/codegen/blackbox/synchronized/exceptionInMonitorExpression.kt b/backend.native/tests/external/codegen/blackbox/synchronized/exceptionInMonitorExpression.kt new file mode 100644 index 00000000000..e0180c1e7a3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/synchronized/exceptionInMonitorExpression.kt @@ -0,0 +1,20 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String { + val obj = "" as java.lang.Object + val e = IllegalArgumentException() + fun m(): Nothing = throw e + try { + synchronized (m()) { + throw AssertionError("Should not have reached this point") + } + } + catch (caught: Throwable) { + if (caught !== e) return "Fail: $caught" + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/synchronized/finally.kt b/backend.native/tests/external/codegen/blackbox/synchronized/finally.kt new file mode 100644 index 00000000000..0cae07f34f0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/synchronized/finally.kt @@ -0,0 +1,33 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +fun box(): String { + val obj = "" as java.lang.Object + + val e = IllegalArgumentException() + try { + synchronized (obj) { + throw e + } + } + catch (caught: Throwable) { + if (caught !== e) return "Fail: $caught" + // If monitorexit didn't happen (a finally block failed), this assertion would fail + assertThatThreadDoesNotOwnMonitor(obj) + } + + return "OK" +} + +fun assertThatThreadDoesNotOwnMonitor(obj: java.lang.Object) { + try { + obj.wait(1) + throw IllegalStateException("Not owning a monitor!") + } + catch (e: IllegalMonitorStateException) { + // OK + } +} diff --git a/backend.native/tests/external/codegen/blackbox/synchronized/longValue.kt b/backend.native/tests/external/codegen/blackbox/synchronized/longValue.kt new file mode 100644 index 00000000000..c06a4efd2a1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/synchronized/longValue.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String { + var obj = "0" as java.lang.Object + val result = synchronized (obj) { + 239L + } + + if (result != 239L) return "Fail: $result" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/synchronized/nestedDifferentObjects.kt b/backend.native/tests/external/codegen/blackbox/synchronized/nestedDifferentObjects.kt new file mode 100644 index 00000000000..369f1266120 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/synchronized/nestedDifferentObjects.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String { + val obj = "" as java.lang.Object + val obj2 = "1" as java.lang.Object + + synchronized (obj) { + synchronized (obj2) { + obj.wait(1) + obj2.wait(1) + } + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/synchronized/nestedSameObject.kt b/backend.native/tests/external/codegen/blackbox/synchronized/nestedSameObject.kt new file mode 100644 index 00000000000..8f451dfd855 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/synchronized/nestedSameObject.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String { + val obj = "" as java.lang.Object + + synchronized (obj) { + synchronized (obj) { + obj.wait(1) + } + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/synchronized/nonLocalReturn.kt b/backend.native/tests/external/codegen/blackbox/synchronized/nonLocalReturn.kt new file mode 100644 index 00000000000..de47313baa5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/synchronized/nonLocalReturn.kt @@ -0,0 +1,182 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +import java.util.concurrent.CountDownLatch +import java.util.concurrent.TimeUnit +import java.util.concurrent.Executors +import java.util.concurrent.Callable +import java.util.concurrent.Future + +val count: Int = 10; +var index: Int = 0; +val doneSignal = CountDownLatch(count) +val startSignal = CountDownLatch(1); +val mutex: Any = Object() +val results = arrayListOf() +val executorService = Executors.newFixedThreadPool(count) + +class MyException(message: String): Exception(message) + +enum class ExecutionType { + LOCAL, + NON_LOCAL_SIMPLE, + NON_LOCAL_EXCEPTION, + NON_LOCAL_FINALLY, + NON_LOCAL_EXCEPTION_AND_FINALLY, + NON_LOCAL_EXCEPTION_AND_FINALLY_WITH_RETURN, + NON_LOCAL_NESTED +} + +class TestLocal(val name: String, val executionType: ExecutionType) : Callable { + + override fun call(): String { + startSignal.await() + return when (executionType) { + ExecutionType.LOCAL -> local() + ExecutionType.NON_LOCAL_SIMPLE -> nonLocalSimple() + ExecutionType.NON_LOCAL_EXCEPTION -> nonLocalWithException() + ExecutionType.NON_LOCAL_FINALLY -> nonLocalWithFinally() + ExecutionType.NON_LOCAL_EXCEPTION_AND_FINALLY -> nonLocalWithExceptionAndFinally() + ExecutionType.NON_LOCAL_EXCEPTION_AND_FINALLY_WITH_RETURN -> nonLocalWithExceptionAndFinallyWithReturn() + ExecutionType.NON_LOCAL_NESTED -> nonLocalNested() + else -> "fail" + } + } + + private fun underMutexFun() { + results.add(++index); + doneSignal.countDown() + } + + fun local(): String { + synchronized(mutex) { + underMutexFun() + } + return executionType.toString() + } + + + fun nonLocalSimple(): String { + synchronized(mutex) { + underMutexFun() + return executionType.name + } + return "fail" + } + + fun nonLocalWithException(): String { + synchronized(mutex) { + try { + underMutexFun() + throw MyException(executionType.name) + } catch (e: MyException) { + return e.message!! + } + } + return "fail" + } + + fun nonLocalWithFinally(): String { + synchronized(mutex) { + try { + underMutexFun() + return "fail" + } finally { + return executionType.name + } + } + return "fail" + } + + fun nonLocalWithExceptionAndFinally(): String { + synchronized(mutex) { + try { + underMutexFun() + throw MyException(executionType.name) + } catch (e: MyException) { + return e.message!! + } finally { + "123" + } + } + return "fail" + } + + fun nonLocalWithExceptionAndFinallyWithReturn(): String { + synchronized(mutex) { + try { + underMutexFun() + throw MyException(executionType.name) + } catch (e: MyException) { + return "fail1" + } finally { + return executionType.name + } + } + return "fail" + } + + fun nonLocalNested(): String { + synchronized(mutex) { + try { + try { + underMutexFun() + throw MyException(executionType.name) + } catch (e: MyException) { + return "fail1" + } finally { + return executionType.name + } + } finally { + val p = 1 + 1 + } + } + return "fail" + } +} + +fun testTemplate(type: ExecutionType, producer: (Int) -> Callable): String { + + try { + val futures = arrayListOf>() + for (i in 1..count) { + futures.add(executorService.submit (producer(i))) + } + + startSignal.countDown() + val b = doneSignal.await(10, TimeUnit.SECONDS) + if (!b) return "fail: processes not finished" + + for (i in 1..count) { + if (results[i - 1] != i) + return "fail $i != ${results[i]}: synchronization not works : " + results.joinToString() + } + + for (f in futures) { + if (f.get() != type.name) return "failed result ${f.get()} != ${type.name}" + } + } finally { + + } + + return "OK" +} + +fun runTest(type: ExecutionType): String { + return testTemplate (type) { TestLocal(it.toString(), type) } +} + +fun box(): String { + try { + for (type in ExecutionType.values()) { + val result = runTest(type) + if (result != "OK") return "fail on $type execution: $result" + } + } finally { + executorService.shutdown() + } + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/synchronized/objectValue.kt b/backend.native/tests/external/codegen/blackbox/synchronized/objectValue.kt new file mode 100644 index 00000000000..d1d2acd2e88 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/synchronized/objectValue.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String { + var obj = "0" as java.lang.Object + val result = synchronized (obj) { + "239" + } + + if (result != "239") return "Fail: $result" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/synchronized/sync.kt b/backend.native/tests/external/codegen/blackbox/synchronized/sync.kt new file mode 100644 index 00000000000..e08ad511b68 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/synchronized/sync.kt @@ -0,0 +1,39 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +import java.util.concurrent.* +import java.util.concurrent.atomic.* + +fun thread(block: ()->Unit ) { + val thread = object: Thread() { + override fun run() { + block() + } + } + thread.start() +} + +fun box() : String { + val mtref = AtomicInteger() + val cdl = CountDownLatch(11) + for(i in 0..10) { + thread { + var current = 0 + do { + current = synchronized(mtref) { + val v = mtref.get() + 1 + if(v < 100) + mtref.set(v+1) + v + } + } + while(current < 100) + cdl.countDown() + } + } + cdl.await() + return if(mtref.get() == 100) "OK" else mtref.get().toString() +} diff --git a/backend.native/tests/external/codegen/blackbox/synchronized/value.kt b/backend.native/tests/external/codegen/blackbox/synchronized/value.kt new file mode 100644 index 00000000000..1f04c749df4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/synchronized/value.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun box(): String { + var obj = "0" as java.lang.Object + val result = synchronized (obj) { + 239 + } + + if (result != 239) return "Fail: $result" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/synchronized/wait.kt b/backend.native/tests/external/codegen/blackbox/synchronized/wait.kt new file mode 100644 index 00000000000..64b788e3593 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/synchronized/wait.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FULL_JDK + +fun box(): String { + val obj = "" as java.lang.Object + try { + obj.wait(1) + return "Fail: exception should have been thrown" + } + catch (e: IllegalMonitorStateException) { + // OK + } + + synchronized (obj) { + obj.wait(1) + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/syntheticAccessors/accessorForProtected.kt b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/accessorForProtected.kt new file mode 100644 index 00000000000..6250b18d1ce --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/accessorForProtected.kt @@ -0,0 +1,38 @@ +// FILE: 1.kt + +import b.B +import a.BSamePackage + +fun box() = if (B().test() == BSamePackage().test()) "OK" else "fail" + +// FILE: 2.kt + +package a + +open class A { + protected fun protectedFun(): String = "OK" +} + +class BSamePackage: A() { + fun test(): String { + val a = { + protectedFun() + } + return a() + } +} + +// FILE: 3.kt + +package b + +import a.A + +class B: A() { + fun test(): String { + val a = { + protectedFun() + } + return a() + } +} diff --git a/backend.native/tests/external/codegen/blackbox/syntheticAccessors/accessorForProtectedInvokeVirtual.kt b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/accessorForProtectedInvokeVirtual.kt new file mode 100644 index 00000000000..f68dda4d4b1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/accessorForProtectedInvokeVirtual.kt @@ -0,0 +1,68 @@ +// WITH_RUNTIME +// FILE: 1.kt + +import test.A +import kotlin.test.assertEquals + +open class B : A() { + fun box(): String { + val overriddenMethod: () -> String = { + method() + } + assertEquals("C.method", overriddenMethod()) + + val superMethod: () -> String = { + super.method() + } + assertEquals("A.method", superMethod()) + + val overriddenPropertyGetter: () -> String = { + property + } + assertEquals("C.property", overriddenPropertyGetter()) + + val superPropertyGetter: () -> String = { + super.property + } + assertEquals("A.property", superPropertyGetter()) + + val overriddenPropertySetter: () -> Unit = { + property = "" + } + overriddenPropertySetter() + + val superPropertySetter: () -> Unit = { + super.property = "" + } + superPropertySetter() + + assertEquals("C.property;A.property;", state) + + return "OK" + } +} + +class C : B() { + override fun method() = "C.method" + override var property: String + get() = "C.property" + set(value) { state += "C.property;" } +} + +fun box() = C().box() + +// FILE: 2.kt + +package test + +abstract class A { + public var state = "" + + // These implementations should not be called, because they are overridden in C + + protected open fun method(): String = "A.method" + + protected open var property: String + get() = "A.property" + set(value) { state += "A.property;" } +} diff --git a/backend.native/tests/external/codegen/blackbox/syntheticAccessors/kt10047.kt b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/kt10047.kt new file mode 100644 index 00000000000..8317ac0f765 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/kt10047.kt @@ -0,0 +1,36 @@ +// FILE: a.kt + +package test2 + +import test.Actor +import test.O2dScriptAction + +class CompositeActor : Actor() + +public open class O2dDialog : O2dScriptAction() { + + fun test() = { owner }() + + fun test2() = { calc() }() +} + +fun box(): String { + if (O2dDialog().test() != null) return "fail 1" + if (O2dDialog().test2() != null) return "fail 2" + + return "OK" +} + +// FILE: b.kt + +package test + +open class Actor + +abstract public class O2dScriptAction { + protected var owner: T? = null + private set + + protected fun calc(): T? = null + +} diff --git a/backend.native/tests/external/codegen/blackbox/syntheticAccessors/kt9717.kt b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/kt9717.kt new file mode 100644 index 00000000000..f2438b5a591 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/kt9717.kt @@ -0,0 +1,12 @@ +// FILE: box.kt + +object Test { + val test: String = OK +} + +fun box(): String = Test.test + +// FILE: Vars.kt + +public var OK: String = "OK" + private set diff --git a/backend.native/tests/external/codegen/blackbox/syntheticAccessors/kt9717DifferentPackages.kt b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/kt9717DifferentPackages.kt new file mode 100644 index 00000000000..d201d7c2a39 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/kt9717DifferentPackages.kt @@ -0,0 +1,23 @@ +// FILE: a.kt + +package a + +import b.* + +fun box(): String { + BB().ok() + return BB().OK +} + +// FILE: b.kt + +package b + +public open class B { + public var OK: String = "OK" + protected set +} + +public class BB : B() { + public fun ok(): String = OK +} diff --git a/backend.native/tests/external/codegen/blackbox/syntheticAccessors/kt9958.kt b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/kt9958.kt new file mode 100644 index 00000000000..d138dc19fe4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/kt9958.kt @@ -0,0 +1,30 @@ +// FILE: a.kt + +package a + +import b.* + +class B { + companion object : A() {} + + init { + foo() + } +} + +fun box(): String { + B() + return result +} + +// FILE: b.kt + +package b + +var result = "fail" + +abstract class A { + protected fun foo() { + result = "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/syntheticAccessors/kt9958Interface.kt b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/kt9958Interface.kt new file mode 100644 index 00000000000..639bf6b35bb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/kt9958Interface.kt @@ -0,0 +1,32 @@ +// FILE: a.kt + +package a + +import b.* + +interface B { + companion object : A() {} + + fun test() { + foo() + } +} + +class C : B + +fun box(): String { + C().test() + return result +} + +// FILE: b.kt + +package b + +var result = "fail" + +abstract class A { + protected fun foo() { + result = "OK" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/syntheticAccessors/protectedFromLambda.kt b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/protectedFromLambda.kt new file mode 100644 index 00000000000..a0cb7165308 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/protectedFromLambda.kt @@ -0,0 +1,28 @@ +// FILE: A.kt + +package first +import second.C + +open class A { + protected open fun test(): String = "FAIL (A)" +} + +fun box() = C().value() + +// FILE: B.kt + +// See also KT-8344: INVOKESPECIAL instead of INVOKEVIRTUAL in accessor + +package second + +import first.A + +public abstract class B(): A() { + val value = { + test() + } +} + +class C: B() { + override fun test() = "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/syntheticAccessors/syntheticAccessorNames.kt b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/syntheticAccessorNames.kt new file mode 100644 index 00000000000..7f90fb35831 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/syntheticAccessors/syntheticAccessorNames.kt @@ -0,0 +1,46 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// This test checks that synthetic accessors generated by Kotlin compiler have names starting with "access$" +// This is crucial for some JVM frameworks like Quasar which rely on the bytecode being similar to the one generated by javac +// See https://youtrack.jetbrains.com/issue/KT-6870 + +class PrivatePropertyGet { + private val x = 42 + + inner class Inner { val a = x } +} + +class PrivatePropertySet { + private var x = "a" + + inner class Inner { init { x = "b" } } +} + +class PrivateMethod { + private fun foo() = "" + + inner class Inner { val a = foo() } +} + +fun check(klass: Class<*>) { + for (method in klass.getDeclaredMethods()) { + if (method.isSynthetic() && method.getName().startsWith("access$")) return + } + + throw AssertionError("No synthetic methods starting with 'access$' found in class $klass") +} + +fun box(): String { + check(PrivatePropertyGet::class.java) + check(PrivatePropertySet::class.java) + check(PrivateMethod::class.java) + + // Also check that synthetic accessors really work + PrivatePropertyGet().Inner() + PrivatePropertySet().Inner() + PrivateMethod().Inner() + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/toArray/kt3177-toTypedArray.kt b/backend.native/tests/external/codegen/blackbox/toArray/kt3177-toTypedArray.kt new file mode 100644 index 00000000000..6d941babc19 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/toArray/kt3177-toTypedArray.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME + +fun box(): String { + val list = ArrayList>() + list.add(Pair("Sample", "http://cyber.law.harvard.edu/rss/examples/rss2sample.xml")) + list.add(Pair("Scripting", "http://static.scripting.com/rss.xml")) + + val keys = list.map { it.first }.toTypedArray() + + val keysToString = keys.contentToString() + if (keysToString != "[Sample, Scripting]") return keysToString + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/toArray/returnToTypedArray.kt b/backend.native/tests/external/codegen/blackbox/toArray/returnToTypedArray.kt new file mode 100644 index 00000000000..5986dbe5bf4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/toArray/returnToTypedArray.kt @@ -0,0 +1,10 @@ +// WITH_RUNTIME + +fun getCopyToArray(): Array = listOf(2, 3, 9).toTypedArray() + +fun box(): String { + val str = getCopyToArray().contentToString() + if (str != "[2, 3, 9]") return str + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/toArray/toArray.kt b/backend.native/tests/external/codegen/blackbox/toArray/toArray.kt new file mode 100644 index 00000000000..0475226a268 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/toArray/toArray.kt @@ -0,0 +1,23 @@ +// TARGET_BACKEND: JVM + +// WITH_RUNTIME + +class MyCollection(val delegate: Collection): Collection by delegate + +fun box(): String { + val collection = MyCollection(listOf(2, 3, 9)) as java.util.Collection<*> + + val array1 = collection.toArray() + val array2 = collection.toArray(arrayOfNulls(3) as Array) + + if (!array1.isArrayOf()) return (array1 as Object).getClass().toString() + if (!array2.isArrayOf()) return (array2 as Object).getClass().toString() + + val s1 = array1.contentToString() + val s2 = array2.contentToString() + + if (s1 != "[2, 3, 9]") return "s1 = $s1" + if (s2 != "[2, 3, 9]") return "s2 = $s2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/toArray/toArrayAlreadyPresent.kt b/backend.native/tests/external/codegen/blackbox/toArray/toArrayAlreadyPresent.kt new file mode 100644 index 00000000000..3be85f8dad4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/toArray/toArrayAlreadyPresent.kt @@ -0,0 +1,40 @@ +// TARGET_BACKEND: JVM + +// WITH_RUNTIME + +import java.util.Arrays + +class MyCollection(val delegate: Collection): Collection by delegate { + public fun toArray(): Array { + val a = arrayOfNulls(3) + a[0] = 0 + a[1] = 1 + a[2] = 2 + return a + } + public fun toArray(array: Array): Array { + val asIntArray = array as Array + asIntArray[0] = 0 + asIntArray[1] = 1 + asIntArray[2] = 2 + return array + } +} + +fun box(): String { + val collection = MyCollection(Arrays.asList(2, 3, 9)) as java.util.Collection<*> + + val array1 = collection.toArray() + val array2 = collection.toArray(arrayOfNulls(3) as Array) + + if (!array1.isArrayOf()) return (array1 as Object).getClass().toString() + if (!array2.isArrayOf()) return (array2 as Object).getClass().toString() + + val s1 = Arrays.toString(array1) + val s2 = Arrays.toString(array2) + + if (s1 != "[0, 1, 2]") return "s1 = $s1" + if (s2 != "[0, 1, 2]") return "s2 = $s2" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/toArray/toArrayShouldBePublic.kt b/backend.native/tests/external/codegen/blackbox/toArray/toArrayShouldBePublic.kt new file mode 100644 index 00000000000..3e0d76bede1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/toArray/toArrayShouldBePublic.kt @@ -0,0 +1,50 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME + +// FILE: SingletonCollection.kt +package test + +open class SingletonCollection(val value: T) : AbstractCollection() { + override val size = 1 + override fun iterator(): Iterator = listOf(value).iterator() + + protected fun toArray(): Array = + arrayOf(value) + + protected fun toArray(a: Array): Array { + a[0] = value as E + return a + } +} + +// FILE: DerivedSingletonCollection.kt +package test2 + +import test.* + +class DerivedSingletonCollection(value: T) : SingletonCollection(value) + +// FILE: box.kt +import test.* +import test2.* + +fun box(): String { + val sc = SingletonCollection(42) + + val test1 = (sc as java.util.Collection).toArray() + if (test1[0] != 42) return "Failed #1" + + val test2 = arrayOf(0) + (sc as java.util.Collection).toArray(test2) + if (test2[0] != 42) return "Failed #2" + + val dsc = DerivedSingletonCollection(42) + val test3 = (dsc as java.util.Collection).toArray() + if (test3[0] != 42) return "Failed #3" + + val test4 = arrayOf(0) + (dsc as java.util.Collection).toArray(test4) + if (test4[0] != 42) return "Failed #4" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/toArray/toArrayShouldBePublicWithJava.kt b/backend.native/tests/external/codegen/blackbox/toArray/toArrayShouldBePublicWithJava.kt new file mode 100644 index 00000000000..ff00b887294 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/toArray/toArrayShouldBePublicWithJava.kt @@ -0,0 +1,68 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME + +// FILE: SingletonCollection.kt +package test + +open class SingletonCollection(val value: T) : AbstractCollection() { + override val size = 1 + override fun iterator(): Iterator = listOf(value).iterator() + + protected open fun toArray(): Array = + arrayOf(value) + + protected open fun toArray(a: Array): Array { + a[0] = value as E + return a + } +} + +// FILE: JavaSingletonCollection.java +import test.*; + +public class JavaSingletonCollection extends SingletonCollection { + public JavaSingletonCollection(T value) { + super(value); + } +} + +// FILE: JavaSingletonCollection2.java +import test.*; + +public class JavaSingletonCollection2 extends SingletonCollection { + public JavaSingletonCollection2(T value) { + super(value); + } + + public Object[] toArray() { + return super.toArray(); + } + + public E[] toArray(E[] arr) { + return super.toArray(arr); + } +} + + +// FILE: box.kt +import test.* + +fun box(): String { + val jsc = JavaSingletonCollection(42) as java.util.Collection + val test3 = jsc.toArray() + if (test3[0] != 42) return "Failed #3" + + val test4 = arrayOf(0) + jsc.toArray(test4) + if (test4[0] != 42) return "Failed #4" + + val jsc2 = JavaSingletonCollection2(42) as java.util.Collection + val test5 = jsc2.toArray() + if (test5[0] != 42) return "Failed #5" + + val test6 = arrayOf(0) + jsc2.toArray(test6) + if (test6[0] != 42) return "Failed #6" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/toArray/toTypedArray.kt b/backend.native/tests/external/codegen/blackbox/toArray/toTypedArray.kt new file mode 100644 index 00000000000..4a98b0cf943 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/toArray/toTypedArray.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE +// missing isArrayOf on JS + +// WITH_RUNTIME + +fun box(): String { + val array = listOf(2, 3, 9).toTypedArray() + if (!array.isArrayOf()) return "fail: is not Array" + + val str = array.contentToString() + if (str != "[2, 3, 9]") return str + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/topLevelPrivate/noPrivateNoAccessorsInMultiFileFacade.kt b/backend.native/tests/external/codegen/blackbox/topLevelPrivate/noPrivateNoAccessorsInMultiFileFacade.kt new file mode 100644 index 00000000000..e464f276b32 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/topLevelPrivate/noPrivateNoAccessorsInMultiFileFacade.kt @@ -0,0 +1,25 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@file:kotlin.jvm.JvmMultifileClass +@file:kotlin.jvm.JvmName("TestKt") +package test + +import kotlin.test.assertEquals + +private var prop = "O" + +private fun test() = "K" + +fun box(): String { + + val clazz = Class.forName("test.TestKt") + assertEquals(1, clazz.declaredMethods.size, "Facade should have only box and getProp methods") + assertEquals("box", clazz.declaredMethods.first().name, "Facade should have only box method") + + return { + prop + test() + }() +} diff --git a/backend.native/tests/external/codegen/blackbox/topLevelPrivate/noPrivateNoAccessorsInMultiFileFacade2.kt b/backend.native/tests/external/codegen/blackbox/topLevelPrivate/noPrivateNoAccessorsInMultiFileFacade2.kt new file mode 100644 index 00000000000..a0a275444d4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/topLevelPrivate/noPrivateNoAccessorsInMultiFileFacade2.kt @@ -0,0 +1,30 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@file:kotlin.jvm.JvmMultifileClass +@file:kotlin.jvm.JvmName("TestKt") +package test + +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +public var prop = "fail" + private set + +private fun test() = "K" + +fun box(): String { + + val clazz = Class.forName("test.TestKt") + assertEquals(2, clazz.declaredMethods.size, "Facade should have only box method") + val methods = clazz.declaredMethods.map { it.name } + assertTrue(methods.contains("box"), "Facade should have box method") + assertTrue(methods.contains("getProp"), "Facade should have box method") + + return { + prop = "O" + prop + test() + }() +} diff --git a/backend.native/tests/external/codegen/blackbox/topLevelPrivate/privateInInlineNested.kt b/backend.native/tests/external/codegen/blackbox/topLevelPrivate/privateInInlineNested.kt new file mode 100644 index 00000000000..2f43f6e7930 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/topLevelPrivate/privateInInlineNested.kt @@ -0,0 +1,19 @@ +package test + +private val prop = "O" + +private fun test() = "K" + +inline internal fun call(p: () -> String): String = p() + +inline internal fun inlineFun(): String { + return call { + object { + fun run() = prop + test() + }.run() + } +} + +fun box(): String { + return inlineFun(); +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/topLevelPrivate/privateVisibility.kt b/backend.native/tests/external/codegen/blackbox/topLevelPrivate/privateVisibility.kt new file mode 100644 index 00000000000..b8fde078208 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/topLevelPrivate/privateVisibility.kt @@ -0,0 +1,21 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FULL_JDK +package test + +import java.lang.reflect.Modifier + +private val prop = "O" + +private fun test() = "K" + +fun box(): String { + val clazz = Class.forName("test.PrivateVisibilityKt") + if (!Modifier.isPrivate(clazz.getDeclaredMethod("test").modifiers)) + return "Private top level function should be private" + if (!Modifier.isPrivate(clazz.getDeclaredField("prop").modifiers)) + return "Backing field for private top level property should be private" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/topLevelPrivate/syntheticAccessor.kt b/backend.native/tests/external/codegen/blackbox/topLevelPrivate/syntheticAccessor.kt new file mode 100644 index 00000000000..68d402f57bc --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/topLevelPrivate/syntheticAccessor.kt @@ -0,0 +1,11 @@ +package test + +private val prop = "O" + +private fun test() = "K" + +fun box(): String { + return { + prop + test() + }() +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/topLevelPrivate/syntheticAccessorInMultiFile.kt b/backend.native/tests/external/codegen/blackbox/topLevelPrivate/syntheticAccessorInMultiFile.kt new file mode 100644 index 00000000000..65ed58cc260 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/topLevelPrivate/syntheticAccessorInMultiFile.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +@file:kotlin.jvm.JvmMultifileClass +@file:kotlin.jvm.JvmName("TestKt") +package test + +private val prop = "O" + +private fun test() = "K" + +fun box(): String { + return { + prop + test() + }() +} diff --git a/backend.native/tests/external/codegen/blackbox/traits/abstractClassInheritsFromInterface.kt b/backend.native/tests/external/codegen/blackbox/traits/abstractClassInheritsFromInterface.kt new file mode 100644 index 00000000000..627b60834d9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/abstractClassInheritsFromInterface.kt @@ -0,0 +1,22 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: ExtendsKCWithT.java + +public class ExtendsKCWithT extends KC { + public static String bar() { + return new ExtendsKCWithT().foo(); + } +} + +// FILE: KC.kt + +// KT-3407 Implementing (in Java) an abstract Kotlin class that implements a trait does not respect trait method definition + +interface T { + fun foo() = "OK" +} + +abstract class KC: T {} + +fun box() = ExtendsKCWithT.bar() diff --git a/backend.native/tests/external/codegen/blackbox/traits/diamondPropertyAccessors.kt b/backend.native/tests/external/codegen/blackbox/traits/diamondPropertyAccessors.kt new file mode 100644 index 00000000000..a0eede09d5a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/diamondPropertyAccessors.kt @@ -0,0 +1,26 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +interface A { + var bar: Boolean + get() = false + set(value) { throw AssertionError("Fail set") } +} + +interface B : A + +interface C : A { + override var bar: Boolean + get() = true + set(value) {} +} + +interface D : B, C + +class Impl : D + +fun box(): String { + Impl().bar = false + if (!Impl().bar) return "Fail get" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/traits/genericMethod.kt b/backend.native/tests/external/codegen/blackbox/traits/genericMethod.kt new file mode 100644 index 00000000000..e3d47b24181 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/genericMethod.kt @@ -0,0 +1,21 @@ +interface A { + val property : T + + open fun a() : T { + return property + } +} + +open class B : A { + + override val property: Any = "fail" +} + +open class C : B(), A { + + override val property: Any = "OK" +} + +fun box() : String { + return C().a() as String +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/traits/indirectlyInheritPropertyGetter.kt b/backend.native/tests/external/codegen/blackbox/traits/indirectlyInheritPropertyGetter.kt new file mode 100644 index 00000000000..75cde1daa46 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/indirectlyInheritPropertyGetter.kt @@ -0,0 +1,10 @@ +interface A { + val str: String + get() = "OK" +} + +interface B : A + +class Impl : B + +fun box() = Impl().str diff --git a/backend.native/tests/external/codegen/blackbox/traits/inheritJavaInterface.kt b/backend.native/tests/external/codegen/blackbox/traits/inheritJavaInterface.kt new file mode 100644 index 00000000000..44f9fac7be5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/inheritJavaInterface.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: MyInt.java + +public interface MyInt { + + String test(); +} + +// FILE: test.kt + +interface A : MyInt { + override public fun test(): String? { + return "OK" + } +} + +class B: A + +fun box() : String { + return B().test()!! +} diff --git a/backend.native/tests/external/codegen/blackbox/traits/inheritedFun.kt b/backend.native/tests/external/codegen/blackbox/traits/inheritedFun.kt new file mode 100644 index 00000000000..756aed226c7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/inheritedFun.kt @@ -0,0 +1,10 @@ +//KT-2206 +interface A { + fun f():Int = 239 +} + +class B() : A + +fun box() : String { + return if (B().f() == 239) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/traits/inheritedVar.kt b/backend.native/tests/external/codegen/blackbox/traits/inheritedVar.kt new file mode 100644 index 00000000000..887f33c2178 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/inheritedVar.kt @@ -0,0 +1,14 @@ +//KT-2206 + +interface A { + var a:Int + get() = 239 + set(value) { + } +} + +class B() : A + +fun box() : String { + return if (B().a == 239) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/traits/interfaceDefaultImpls.kt b/backend.native/tests/external/codegen/blackbox/traits/interfaceDefaultImpls.kt new file mode 100644 index 00000000000..65727b9bdd5 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/interfaceDefaultImpls.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: B.java + +class B { + static String test(A x) { + return A.DefaultImpls.foo(x); + } +} + +// FILE: main.kt + +interface A { + fun foo() = "OK" +} + +fun box(): String { + val result = B.test(object : A {}) + if (result != "OK") return "fail: $result" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/traits/kt1936.kt b/backend.native/tests/external/codegen/blackbox/traits/kt1936.kt new file mode 100644 index 00000000000..0764dca3de4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/kt1936.kt @@ -0,0 +1,23 @@ +var result = "Fail" + +interface MyTrait +{ + var property : String + fun foo() { + result = property + } +} + +open class B(param : String) : MyTrait +{ + override var property : String = param + override fun foo() { + super.foo() + } +} + +fun box(): String { + val b = B("OK") + b.foo() + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/traits/kt1936_1.kt b/backend.native/tests/external/codegen/blackbox/traits/kt1936_1.kt new file mode 100644 index 00000000000..c3c6ef815f6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/kt1936_1.kt @@ -0,0 +1,13 @@ +interface MyTrait +{ + var property : String + fun foo() = property +} + +open class B(param : String) : MyTrait +{ + override var property : String = param + override fun foo() = super.foo() +} + +fun box()= B("OK").foo() diff --git a/backend.native/tests/external/codegen/blackbox/traits/kt2260.kt b/backend.native/tests/external/codegen/blackbox/traits/kt2260.kt new file mode 100644 index 00000000000..f63a2220542 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/kt2260.kt @@ -0,0 +1,9 @@ +interface Flusher { + fun flush() = "OK" +} + +fun myFlusher() = object : Flusher { } + +fun flushIt(flusher: Flusher) = flusher.flush() + +fun box() = flushIt(myFlusher()) diff --git a/backend.native/tests/external/codegen/blackbox/traits/kt2399.kt b/backend.native/tests/external/codegen/blackbox/traits/kt2399.kt new file mode 100644 index 00000000000..54dbd833474 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/kt2399.kt @@ -0,0 +1,44 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE +// on JS Parser.parse and MultiParser.parse clash in ProjectInfoJsonParser + +class JsonObject { +} + +class JsonArray { +} + +class ProjectInfo { + override fun toString(): String = "OK" +} + +public interface Parser { + public fun parse(source: IN): OUT +} + +public interface MultiParser { + public fun parse(source: IN): Collection +} + +public interface JsonParser: Parser, MultiParser { + public override fun parse(source: JsonArray): Collection { + return ArrayList() + } +} + +public abstract class ProjectInfoJsonParser(): JsonParser { + public override fun parse(source: JsonObject): ProjectInfo { + return ProjectInfo() + } +} + +class ProjectApiContext { + public val projectInfoJsonParser: ProjectInfoJsonParser = object : ProjectInfoJsonParser(){ + } +} + +fun box(): String { + val context = ProjectApiContext() + val array = context.projectInfoJsonParser.parse(JsonArray()) + return if (array != null) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/traits/kt2541.kt b/backend.native/tests/external/codegen/blackbox/traits/kt2541.kt new file mode 100644 index 00000000000..5be4abf0272 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/kt2541.kt @@ -0,0 +1,7 @@ +interface A { + fun foo(t: T, u: U) = "OK" +} + +class B : A + +fun box(): String = B().foo(1, 2) diff --git a/backend.native/tests/external/codegen/blackbox/traits/kt3315.kt b/backend.native/tests/external/codegen/blackbox/traits/kt3315.kt new file mode 100644 index 00000000000..91f7f81a489 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/kt3315.kt @@ -0,0 +1,10 @@ +interface B { + fun foo(dd: T): T = dd +} + +class A: B + +fun box(): String { + val a = A() + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/traits/kt3500.kt b/backend.native/tests/external/codegen/blackbox/traits/kt3500.kt new file mode 100644 index 00000000000..94cf3925737 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/kt3500.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +interface BK { + fun foo(): String = 10.toString() +} + +interface KTrait: BK { + override fun foo() = 30.toString() +} + +class A : BK, KTrait { + +} + +fun box(): String { + return if (A().foo() == "30") "OK" else "fail" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/traits/kt3579.kt b/backend.native/tests/external/codegen/blackbox/traits/kt3579.kt new file mode 100644 index 00000000000..64514c50d9b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/kt3579.kt @@ -0,0 +1,8 @@ +open class Persistent(val p: String) +interface Hierarchy where T : Hierarchy + +class Location(): Persistent("OK"), Hierarchy + +fun box(): String { + return Location().p +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/traits/kt3579_2.kt b/backend.native/tests/external/codegen/blackbox/traits/kt3579_2.kt new file mode 100644 index 00000000000..10e9a962302 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/kt3579_2.kt @@ -0,0 +1,10 @@ +interface First +interface Some where T : Some + +val a: Some<*>? = null + +class MClass(val p: String) : First, Some + +fun box(): String { + return MClass("OK").p +} diff --git a/backend.native/tests/external/codegen/blackbox/traits/kt5393.kt b/backend.native/tests/external/codegen/blackbox/traits/kt5393.kt new file mode 100644 index 00000000000..2b221df2cb3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/kt5393.kt @@ -0,0 +1,17 @@ +interface A { + fun foo(): String { + return "OK" + } +} + +interface B : A + +class C : B { + override fun foo(): String { + return super.foo() + } +} + +fun box(): String { + return C().foo() +} diff --git a/backend.native/tests/external/codegen/blackbox/traits/kt5393_property.kt b/backend.native/tests/external/codegen/blackbox/traits/kt5393_property.kt new file mode 100644 index 00000000000..881fb3ba8ca --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/kt5393_property.kt @@ -0,0 +1,20 @@ +var result = "Fail" + +interface A { + var foo: String + get() = result + set(value) { result = value } +} + +interface B : A + +class C : B { + override var foo: String + get() = super.foo + set(value) { super.foo = value } +} + +fun box(): String { + C().foo = "OK" + return C().foo +} diff --git a/backend.native/tests/external/codegen/blackbox/traits/multiple.kt b/backend.native/tests/external/codegen/blackbox/traits/multiple.kt new file mode 100644 index 00000000000..bc6470c0d6b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/multiple.kt @@ -0,0 +1,21 @@ +interface AL { + fun get(index: Int) : Any? = null +} + +interface ALE : AL { + fun getOrNull(index: Int, value: T) : T { + val r = get(index) as? T + return r ?: value + } +} + +open class SmartArrayList() : ALE { +} + +class SmartArrayList2() : SmartArrayList(), AL { +} + +fun box() : String { + val c = SmartArrayList2() + return if("239" == c.getOrNull(0, "239")) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/traits/noPrivateDelegation.kt b/backend.native/tests/external/codegen/blackbox/traits/noPrivateDelegation.kt new file mode 100644 index 00000000000..d1c3bd777bf --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/noPrivateDelegation.kt @@ -0,0 +1,19 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +interface Z{ + + private fun extension(): String { + return "OK" + } +} + +object Z2 : Z { + +} + +fun box() : String { + val size = Class.forName("Z2").declaredMethods.size + if (size != 0) return "fail: $size" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/traits/syntheticAccessor.kt b/backend.native/tests/external/codegen/blackbox/traits/syntheticAccessor.kt new file mode 100644 index 00000000000..32ce13d9d57 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/syntheticAccessor.kt @@ -0,0 +1,21 @@ +var result = "fail" + +interface B { + + private fun test() { + result = "OK" + } + + class Z { + fun ztest(b: B) { + b.test() + } + } +} + +class C : B + +fun box(): String { + B.Z().ztest(C()) + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/traits/traitImplDelegationWithCovariantOverride.kt b/backend.native/tests/external/codegen/blackbox/traits/traitImplDelegationWithCovariantOverride.kt new file mode 100644 index 00000000000..2c8af75f5c0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/traitImplDelegationWithCovariantOverride.kt @@ -0,0 +1,18 @@ +interface A { + fun foo(): Number { + return 42 + } +} + +interface B : A + +class C : B { + override fun foo(): Int { + return super.foo() as Int + } +} + +fun box(): String { + val x = C().foo() + return if (x == 42) "OK" else "Fail: $x" +} diff --git a/backend.native/tests/external/codegen/blackbox/traits/traitImplDiamond.kt b/backend.native/tests/external/codegen/blackbox/traits/traitImplDiamond.kt new file mode 100644 index 00000000000..1fe1ebfad15 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/traitImplDiamond.kt @@ -0,0 +1,18 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +interface A { + fun foo() = "Fail" +} + +interface B : A + +interface C : A { + override fun foo() = "OK" +} + +interface D : B, C + +class Impl : D + +fun box(): String = Impl().foo() diff --git a/backend.native/tests/external/codegen/blackbox/traits/traitImplGenericDelegation.kt b/backend.native/tests/external/codegen/blackbox/traits/traitImplGenericDelegation.kt new file mode 100644 index 00000000000..65253011fd9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/traitImplGenericDelegation.kt @@ -0,0 +1,22 @@ +interface A { + fun foo(t: T, u: U): V? { + return null + } +} + +interface B : A + +class C : B { + override fun foo(t: String, u: Int): Runnable? { + return super.foo(t, u) + } +} + +interface Runnable { + fun run(): Unit +} + +fun box(): String { + val x = C().foo("", 0) + return if (x == null) "OK" else "Fail: $x" +} diff --git a/backend.native/tests/external/codegen/blackbox/traits/traitWithPrivateExtension.kt b/backend.native/tests/external/codegen/blackbox/traits/traitWithPrivateExtension.kt new file mode 100644 index 00000000000..5dee33c0792 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/traitWithPrivateExtension.kt @@ -0,0 +1,28 @@ +open class B { + val p = "OK" +} + +class BB : B() + +interface Z { + fun T.getString() : String { + return p + } + + fun test(s: T) : String { + return s.extension() + } + + private fun T.extension(): String { + return getString() + } +} + +object Z2 : Z { + +} + +fun box() : String { + return Z2.test(BB()) +} + diff --git a/backend.native/tests/external/codegen/blackbox/traits/traitWithPrivateMember.kt b/backend.native/tests/external/codegen/blackbox/traits/traitWithPrivateMember.kt new file mode 100644 index 00000000000..50debaa1e26 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/traitWithPrivateMember.kt @@ -0,0 +1,26 @@ +interface Z { + + fun testFun() : String { + return privateFun() + } + + fun testProperty() : String { + return privateProp + } + + private fun privateFun(): String { + return "O" + } + + private val privateProp: String + get() = "K" +} + +object Z2 : Z { + +} + +fun box() : String { + return Z2.testFun() + Z2.testProperty() +} + diff --git a/backend.native/tests/external/codegen/blackbox/traits/traitWithPrivateMemberAccessFromLambda.kt b/backend.native/tests/external/codegen/blackbox/traits/traitWithPrivateMemberAccessFromLambda.kt new file mode 100644 index 00000000000..0b2a16072d3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/traits/traitWithPrivateMemberAccessFromLambda.kt @@ -0,0 +1,26 @@ +interface Z { + + fun testFun(): String { + return { privateFun() } () + } + + fun testProperty(): String { + return { privateProp } () + } + + private fun privateFun(): String { + return "O" + } + + private val privateProp: String + get() = "K" +} + +object Z2 : Z { + +} + +fun box(): String { + return Z2.testFun() + Z2.testProperty() +} + diff --git a/backend.native/tests/external/codegen/blackbox/typeInfo/asInLoop.kt b/backend.native/tests/external/codegen/blackbox/typeInfo/asInLoop.kt new file mode 100644 index 00000000000..5c10094c85d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typeInfo/asInLoop.kt @@ -0,0 +1,13 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +import java.io.* + +fun foo(args: Array) { + val reader = BufferedReader(InputStreamReader(System.`in`)) + while(true) { + val cmd = reader.readLine() as String + } +} + +fun box() = "OK" diff --git a/backend.native/tests/external/codegen/blackbox/typeInfo/ifOrWhenSpecialCall.kt b/backend.native/tests/external/codegen/blackbox/typeInfo/ifOrWhenSpecialCall.kt new file mode 100644 index 00000000000..54ec5152a12 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typeInfo/ifOrWhenSpecialCall.kt @@ -0,0 +1,26 @@ +interface Option { + val s: String +} +class Some(override val s: String) : Option +class None(override val s: String = "None") : Option + +fun whenTest(a: Int): Option = when (a) { + 239 -> { + if (a == 239) Some("239") else None() + } + else -> if (a != 239) Some("$a") else None() +} + +fun ifTest(a: Int): Option = if (a == 239) { + if (a == 239) Some("239") else None() +} else if (a != 239) Some("$a") else None() + +fun box(): String { + if (whenTest(2).s != "2") return "Fail 1" + if (whenTest(239).s != "239") return "Fail 2" + + if (ifTest(2).s != "2") return "Fail 3" + if (ifTest(239).s != "239") return "Fail 4" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/typeInfo/implicitSmartCastThis.kt b/backend.native/tests/external/codegen/blackbox/typeInfo/implicitSmartCastThis.kt new file mode 100644 index 00000000000..a4587005887 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typeInfo/implicitSmartCastThis.kt @@ -0,0 +1,13 @@ +open class A + +class B : A() { + fun foo(i: Int) = i +} + +fun A.test() = if (this is B) foo(42) else 0 + +fun box(): String { + if (B().test() != 42) return "fail1" + if (A().test() != 0) return "fail2" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/typeInfo/inheritance.kt b/backend.native/tests/external/codegen/blackbox/typeInfo/inheritance.kt new file mode 100644 index 00000000000..f40166007db --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typeInfo/inheritance.kt @@ -0,0 +1,11 @@ +open class A () { + fun plus(e: T) = B (e) +} + +class B (val e: T) : A() { + fun add() = B (e) +} + +fun box() : String { + return if(A().plus("239").add().e == "239" ) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/typeInfo/kt2811.kt b/backend.native/tests/external/codegen/blackbox/typeInfo/kt2811.kt new file mode 100644 index 00000000000..293eb80b20b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typeInfo/kt2811.kt @@ -0,0 +1,25 @@ +open class Test1 { + fun test1(): String { + if (this is Test2) { + return this.foo() + } + return "fail" + } +} + +class Test2(): Test1() { + fun foo(): String { + return "OK" + } +} + +fun Test1.test2(): String { + if (this is Test2) return this.foo() else return "fail" +} + +fun box(): String { + if ("OK" == Test2().test1() && "OK" == Test2().test2()) { + return "OK" + } + return "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/typeInfo/primitiveTypeInfo.kt b/backend.native/tests/external/codegen/blackbox/typeInfo/primitiveTypeInfo.kt new file mode 100644 index 00000000000..ff67d156b7d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typeInfo/primitiveTypeInfo.kt @@ -0,0 +1,13 @@ +class Box(t: T) { + var value = t +} + +fun isIntBox(box: Box): Boolean { + return box is Box<*>; +} + + +fun box(): String { + val box = Box(1) + return if (isIntBox(box)) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/typeInfo/smartCastThis.kt b/backend.native/tests/external/codegen/blackbox/typeInfo/smartCastThis.kt new file mode 100644 index 00000000000..6ed06c50328 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typeInfo/smartCastThis.kt @@ -0,0 +1,11 @@ +package h + +open class A { + fun bar() = if (this is B) this.foo() else "fail" +} + +class B() : A() { + fun foo() = "OK" +} + +fun box() = B().bar() \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/typeMapping/enhancedPrimitives.kt b/backend.native/tests/external/codegen/blackbox/typeMapping/enhancedPrimitives.kt new file mode 100644 index 00000000000..b94098789db --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typeMapping/enhancedPrimitives.kt @@ -0,0 +1,16 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: J.java + +public class J { + // This test checks that although type '@org.jetbrains.annotations.NotNull Integer' is perceived as simple Int, + // it's correctly mapped to 'Lj.l.Integer' by JVM backend + public static String test(@org.jetbrains.annotations.NotNull Integer x) { + return "OK"; + } +} + +// FILE: box.kt + +fun box() = J.test(1) diff --git a/backend.native/tests/external/codegen/blackbox/typeMapping/genericTypeWithNothing.kt b/backend.native/tests/external/codegen/blackbox/typeMapping/genericTypeWithNothing.kt new file mode 100644 index 00000000000..8f6c732f1ef --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typeMapping/genericTypeWithNothing.kt @@ -0,0 +1,86 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +package foo + +import kotlin.reflect.KClass + +class A +class B + +class TestRaw { + val a1: A = A() + val a2: A? = A() + val a3: A = A() + val a4: A? = A() + + var b1: B = B() + var b2: B = B() + + val l: List = listOf() + + fun test1(a: A, b: B>): A? = A() + fun test2(a: A?, b: B): B = B() +} + +class TestNotRaw { + val a1: A = A() + val a2: A>? = A() + val a3: A = A() + val a4: A? = A() + + var b1: B = B() + var b2: B, Int> = B() + + val l: List = listOf() + + fun test1(a: A, b: B>): A? = A() + fun test2(a: A?, b: B>): B = B() +} + +abstract class C { + abstract val foo: A + abstract fun bar(): A? +} + +class C1 : C() { + override val foo = A() + override fun bar() = foo +} +class C2 : C() { + override val foo = A() + override fun bar() = foo +} + +fun testAllDeclaredMembers(klass: KClass<*>, expectedIsRaw: Boolean): String? { + val clazz = klass.java + + for (it in clazz.declaredFields) { + if ((it.type == it.genericType) == expectedIsRaw) return "failed on field '${clazz.simpleName}::${it.name}'" + } + + for (m in clazz.declaredMethods) { + for (i in m.parameterTypes.indices) { + if ((m.parameterTypes[i] == m.genericParameterTypes[i]) == expectedIsRaw) return "failed on type of param#$i of method '${clazz.simpleName}::${m.name}'" + } + if (m.returnType != Void.TYPE && (m.returnType == m.genericReturnType) == expectedIsRaw) return "failed on return type of method '${clazz.simpleName}::${m.name}'" + } + + return null +} + +fun box(): String { + testAllDeclaredMembers(TestRaw::class, expectedIsRaw = true) ?: + testAllDeclaredMembers(TestNotRaw::class, expectedIsRaw = false)?.let { return it } + + if (C1::class.java.superclass != C1::class.java.genericSuperclass) return "failed on C1 superclass" + + if (C2::class.java.superclass == C2::class.java.genericSuperclass) return "failed on C2 superclass" + + testAllDeclaredMembers(C1::class, expectedIsRaw = true) ?: + testAllDeclaredMembers(C2::class, expectedIsRaw = false)?.let { return it } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/typeMapping/kt2831.kt b/backend.native/tests/external/codegen/blackbox/typeMapping/kt2831.kt new file mode 100644 index 00000000000..3ead49d90ad --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typeMapping/kt2831.kt @@ -0,0 +1,16 @@ +// Exception in thread "main" java.lang.VerifyError: (class: org/jetbrains/kannotator/controlFlowBuilder/GraphBuilderInterpreter, method: binaryOperation signature: (Lorg/objectweb/asm/tree/AbstractInsnNode;Lorg/jetbrains/kannotator/controlFlowBuilder/AsmPossibleValues;Lorg/jetbrains/kannotator/controlFlowBuilder/AsmPossibleValues;)Lorg/jetbrains/kannotator/controlFlowBuilder/AsmPossibleValues;) Wrong return type in function + +fun foo(): Nothing = throw Exception() + +fun bar(x: Any): Int { + return when(x) { + is String -> 0 + is Int -> 1 + else -> foo() + } +} + +fun box(): String { + bar(3) + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/typeMapping/kt309.kt b/backend.native/tests/external/codegen/blackbox/typeMapping/kt309.kt new file mode 100644 index 00000000000..873343a37ba --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typeMapping/kt309.kt @@ -0,0 +1,15 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +class N { + fun foo() = null +} + +fun box(): String { + val method = N::class.java.getDeclaredMethod("foo") + if (method.returnType.name != "java.lang.Void") return "Fail: Nothing should be mapped to Void" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/typeMapping/kt3286.kt b/backend.native/tests/external/codegen/blackbox/typeMapping/kt3286.kt new file mode 100644 index 00000000000..8d5c36246f9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typeMapping/kt3286.kt @@ -0,0 +1,13 @@ +fun test(x: Int): String = when(x) { + 0 -> "zero" + 1 -> "one" + 2 -> "two" + else -> blowUpHorribly() + } + +fun blowUpHorribly(): Nothing = throw RuntimeException("Blow up!") + +fun box(): String { + test(1) + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/typeMapping/kt3863.kt b/backend.native/tests/external/codegen/blackbox/typeMapping/kt3863.kt new file mode 100644 index 00000000000..21b6b4acd63 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typeMapping/kt3863.kt @@ -0,0 +1,19 @@ +import kotlin.reflect.KProperty + +// java.lang.VerifyError: (class: NotImplemented, method: get signature: (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object;) Unable to pop operand off an empty stack + +class NotImplemented(){ + operator fun getValue(thisRef: Any?, prop: KProperty<*>): T = notImplemented() + operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: T): Nothing = notImplemented() +} + +fun notImplemented() : Nothing = notImplemented() + +class Test { + val x: Int by NotImplemented() +} + +fun box(): String { + Test() + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/typeMapping/kt3976.kt b/backend.native/tests/external/codegen/blackbox/typeMapping/kt3976.kt new file mode 100644 index 00000000000..47110878e72 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typeMapping/kt3976.kt @@ -0,0 +1,20 @@ +import kotlin.reflect.KProperty + +// java.lang.ClassNotFoundException: kotlin.Nothing + +var currentAccountId: Int? by SessionAccessor() +class SessionAccessor { + operator fun getValue(o : Nothing?, desc: KProperty<*>): T { + return null as T + } + + operator fun setValue(o : Nothing?, desc: KProperty<*>, value: T) { + + } +} + +fun box(): String { + currentAccountId = 1 + if (currentAccountId != null) return "Fail" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/typeMapping/nothing.kt b/backend.native/tests/external/codegen/blackbox/typeMapping/nothing.kt new file mode 100644 index 00000000000..93cafb65401 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typeMapping/nothing.kt @@ -0,0 +1,5 @@ +fun box(): String { + // kotlin.Nothing should not be loaded here + val x = "" is Nothing + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/typeMapping/nullableNothing.kt b/backend.native/tests/external/codegen/blackbox/typeMapping/nullableNothing.kt new file mode 100644 index 00000000000..79fd2fa060f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typeMapping/nullableNothing.kt @@ -0,0 +1,5 @@ +fun box(): String { + // This used to be problematic because of an attempt to load kotlin/Nothing class + val x = "" is Nothing? + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/typeMapping/typeParameterMultipleBounds.kt b/backend.native/tests/external/codegen/blackbox/typeMapping/typeParameterMultipleBounds.kt new file mode 100644 index 00000000000..138c2d51355 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typeMapping/typeParameterMultipleBounds.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +interface I1 +interface I2 +open class C + +interface K { + // Erasure of a type parameter with multiple bounds should be the class bound, or the first bound if there's no class bound + + fun c1(t: T) where T : C, T : I1, T : I2 + fun c2(t: T) where T : I1, T : C, T : I2 + fun c3(t: T) where T : I2, T : C, T : I1 + fun c4(t: T) where T : I2, T : I1, T : C + + fun i1(t: T) where T : I1, T : I2 + fun i2(t: T) where T : I2, T : I1 +} + +fun box(): String { + val k = K::class.java + + k.getDeclaredMethod("c1", C::class.java) + k.getDeclaredMethod("c2", C::class.java) + k.getDeclaredMethod("c3", C::class.java) + k.getDeclaredMethod("c4", C::class.java) + + k.getDeclaredMethod("i1", I1::class.java) + k.getDeclaredMethod("i2", I2::class.java) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/typealias/genericTypeAliasConstructor.kt b/backend.native/tests/external/codegen/blackbox/typealias/genericTypeAliasConstructor.kt new file mode 100644 index 00000000000..6dfe839c270 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typealias/genericTypeAliasConstructor.kt @@ -0,0 +1,6 @@ +class Cell(val x: T) + +typealias StringCell = Cell + +fun box(): String = + StringCell("O").x + Cell("K").x \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/typealias/innerClassTypeAliasConstructor.kt b/backend.native/tests/external/codegen/blackbox/typealias/innerClassTypeAliasConstructor.kt new file mode 100644 index 00000000000..6193b148048 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typealias/innerClassTypeAliasConstructor.kt @@ -0,0 +1,10 @@ +class Outer(val x: String) { + inner class Inner(val y: String) { + val z = x + y + } +} + +typealias OI = Outer.Inner + +fun box(): String = + Outer("O").OI("K").z \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/typealias/innerClassTypeAliasConstructorInSupertypes.kt b/backend.native/tests/external/codegen/blackbox/typealias/innerClassTypeAliasConstructorInSupertypes.kt new file mode 100644 index 00000000000..0c1b2ee469f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typealias/innerClassTypeAliasConstructorInSupertypes.kt @@ -0,0 +1,12 @@ +class Outer(val x: String) { + abstract inner class InnerBase + + inner class Inner(val y: String) : OIB() { + val z = x + y + } +} + +typealias OIB = Outer.InnerBase + +fun box(): String = + Outer("O").Inner("K").z \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/typealias/simple.kt b/backend.native/tests/external/codegen/blackbox/typealias/simple.kt new file mode 100644 index 00000000000..a5cd67b9ad7 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typealias/simple.kt @@ -0,0 +1,7 @@ +typealias S = String + +typealias SF = (T) -> S + +val f: SF = { it } + +fun box(): S = f("OK") diff --git a/backend.native/tests/external/codegen/blackbox/typealias/typeAliasAsBareType.kt b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasAsBareType.kt new file mode 100644 index 00000000000..eed82fc0045 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasAsBareType.kt @@ -0,0 +1,11 @@ +// WITH_RUNTIME + +typealias L = List + +fun box(): String { + val test: Collection = listOf(1, 2, 3) + if (test !is L) return "test !is L" + val test2 = test as L + if (test.toList() != test2) return "test.toList() != test2" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/typealias/typeAliasCompanion.kt b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasCompanion.kt new file mode 100644 index 00000000000..07efa97a0f0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasCompanion.kt @@ -0,0 +1,9 @@ +class A { + companion object { + val result = "OK" + } +} + +typealias Alias = A.Companion + +fun box(): String = Alias.result diff --git a/backend.native/tests/external/codegen/blackbox/typealias/typeAliasConstructor.kt b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasConstructor.kt new file mode 100644 index 00000000000..d466f977248 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasConstructor.kt @@ -0,0 +1,5 @@ +class C(val x: String) + +typealias Alias = C + +fun box(): String = Alias("OK").x diff --git a/backend.native/tests/external/codegen/blackbox/typealias/typeAliasConstructorAccessor.kt b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasConstructorAccessor.kt new file mode 100644 index 00000000000..3b92f4005d2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasConstructorAccessor.kt @@ -0,0 +1,10 @@ +class Outer private constructor(public val x: String) { + class Nested { + fun foo() = OuterAlias("OK") + } +} + +typealias OuterAlias = Outer + +fun box(): String = + Outer.Nested().foo().x \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/typealias/typeAliasConstructorInSuperCall.kt b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasConstructorInSuperCall.kt new file mode 100644 index 00000000000..95cee2f88ef --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasConstructorInSuperCall.kt @@ -0,0 +1,10 @@ +open class Cell(val value: T) + +typealias CT = Cell +typealias CStr = Cell + +class C1 : CT("O") +class C2 : CStr("K") + +fun box(): String = + C1().value + C2().value \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/typealias/typeAliasInAnonymousObjectType.kt b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasInAnonymousObjectType.kt new file mode 100644 index 00000000000..ba3a87abaec --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasInAnonymousObjectType.kt @@ -0,0 +1,7 @@ +open class Foo(val x: T) + +typealias FooStr = Foo + +val test = object : FooStr("OK") {} + +fun box() = test.x \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/typealias/typeAliasObject.kt b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasObject.kt new file mode 100644 index 00000000000..203f4e5bd5f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasObject.kt @@ -0,0 +1,15 @@ +object OHolder { + val O = "O" +} + +typealias OHolderAlias = OHolder + +class KHolder { + companion object { + val K = "K" + } +} + +typealias KHolderAlias = KHolder + +fun box(): String = OHolderAlias.O + KHolderAlias.K diff --git a/backend.native/tests/external/codegen/blackbox/typealias/typeAliasObjectCallable.kt b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasObjectCallable.kt new file mode 100644 index 00000000000..5a321ecd586 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasObjectCallable.kt @@ -0,0 +1,9 @@ +object O { + val x = "OK" + + operator fun invoke() = x +} + +typealias A = O + +fun box(): String = A() diff --git a/backend.native/tests/external/codegen/blackbox/typealias/typeAliasSecondaryConstructor.kt b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasSecondaryConstructor.kt new file mode 100644 index 00000000000..fd0f2bd66c9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/typealias/typeAliasSecondaryConstructor.kt @@ -0,0 +1,11 @@ +class C(val x: String) { + constructor(n: Int) : this(n.toString()) +} + +typealias Alias = C + +fun box(): String { + val c = Alias(23) + if (c.x != "23") return "fail: $c" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/unaryOp/call.kt b/backend.native/tests/external/codegen/blackbox/unaryOp/call.kt new file mode 100644 index 00000000000..fe138509d88 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/unaryOp/call.kt @@ -0,0 +1,17 @@ +fun box(): String { + val a1: Byte = 1.unaryMinus() + val a2: Short = 1.unaryMinus() + val a3: Int = 1.unaryMinus() + val a4: Long = 1.unaryMinus() + val a5: Double = 1.0.unaryMinus() + val a6: Float = 1f.unaryMinus() + + if (a1 != (-1).toByte()) return "fail 1" + if (a2 != (-1).toShort()) return "fail -1" + if (a3 != -1) return "fail 3" + if (a4 != -1L) return "fail 4" + if (a5 != -1.0) return "fail 5" + if (a6 != -1f) return "fail 6" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/unaryOp/callNullable.kt b/backend.native/tests/external/codegen/blackbox/unaryOp/callNullable.kt new file mode 100644 index 00000000000..f3ff7db949a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/unaryOp/callNullable.kt @@ -0,0 +1,17 @@ +fun box(): String { + val a1: Byte? = 1.unaryMinus() + val a2: Short? = 1.unaryMinus() + val a3: Int? = 1.unaryMinus() + val a4: Long? = 1.unaryMinus() + val a5: Double? = 1.0.unaryMinus() + val a6: Float? = 1f.unaryMinus() + + if (a1!! != (-1).toByte()) return "fail 1" + if (a2!! != (-1).toShort()) return "fail 2" + if (a3!! != -1) return "fail 3" + if (a4!! != -1L) return "fail 4" + if (a5!! != -1.0) return "fail 5" + if (a6!! != -1f) return "fail 6" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/unaryOp/callWithCommonType.kt b/backend.native/tests/external/codegen/blackbox/unaryOp/callWithCommonType.kt new file mode 100644 index 00000000000..a3fa43dc3c3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/unaryOp/callWithCommonType.kt @@ -0,0 +1,8 @@ +fun box(): String { + if (!foo(1.toByte())) return "fail 1" + if (!foo((1.toByte()).inc())) return "fail 2" + + return "OK" +} + +fun foo(p: Any) = p is Byte \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/unaryOp/intrinsic.kt b/backend.native/tests/external/codegen/blackbox/unaryOp/intrinsic.kt new file mode 100644 index 00000000000..30bd7d9d8f0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/unaryOp/intrinsic.kt @@ -0,0 +1,17 @@ +fun box(): String { + val a1: Byte = -1 + val a2: Short = -1 + val a3: Int = -1 + val a4: Long = -1 + val a5: Double = -1.0 + val a6: Float = -1f + + if (a1 != (-1).toByte()) return "fail 1" + if (a2 != (-1).toShort()) return "fail 2" + if (a3 != -1) return "fail 3" + if (a4 != -1L) return "fail 4" + if (a5 != -1.0) return "fail 5" + if (a6 != -1f) return "fail 6" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/unaryOp/intrinsicNullable.kt b/backend.native/tests/external/codegen/blackbox/unaryOp/intrinsicNullable.kt new file mode 100644 index 00000000000..0463bcddba9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/unaryOp/intrinsicNullable.kt @@ -0,0 +1,17 @@ +fun box(): String { + val a1: Byte? = -1 + val a2: Short? = -1 + val a3: Int? = -1 + val a4: Long? = -1 + val a5: Double? = -1.0 + val a6: Float? = -1f + + if (a1!! != (-1).toByte()) return "fail 1" + if (a2!! != (-1).toShort()) return "fail 2" + if (a3!! != -1) return "fail 3" + if (a4!! != -1L) return "fail 4" + if (a5!! != -1.0) return "fail 5" + if (a6!! != -1f) return "fail 6" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/unaryOp/longOverflow.kt b/backend.native/tests/external/codegen/blackbox/unaryOp/longOverflow.kt new file mode 100644 index 00000000000..d3615f071ea --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/unaryOp/longOverflow.kt @@ -0,0 +1,5 @@ +fun box(): String { + val a: Long = -(1 shl 31) + if (a != -2147483648L) return "fail: in this case we should add to ints and than cast the result to long - overflow expected" + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/unit/UnitValue.kt b/backend.native/tests/external/codegen/blackbox/unit/UnitValue.kt new file mode 100644 index 00000000000..8b5744d17db --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/unit/UnitValue.kt @@ -0,0 +1,8 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun foo() {} + +fun box(): String { + return if (foo() == Unit) "OK" else "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/unit/closureReturnsNullableUnit.kt b/backend.native/tests/external/codegen/blackbox/unit/closureReturnsNullableUnit.kt new file mode 100644 index 00000000000..604b35ab71f --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/unit/closureReturnsNullableUnit.kt @@ -0,0 +1,8 @@ +fun isNull(x: Unit?) = x == null + +fun box(): String { + val closure: () -> Unit? = { null } + if (!isNull(closure())) return "Fail 1" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/unit/ifElse.kt b/backend.native/tests/external/codegen/blackbox/unit/ifElse.kt new file mode 100644 index 00000000000..171b2b2fdeb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/unit/ifElse.kt @@ -0,0 +1,31 @@ +class A (val p: String, p1: String, p2: String) { + + var cond1: String = "" + + var cond2: String = "" + + val prop1 = if (cond1(p)) p1 else null + + val prop2 = if (cond2(p)) p2 else null; + + + fun cond1(p: String): Boolean { + cond1 = "cond1" + return p == "test" + } + + fun cond2(p: String): Boolean { + cond2 = "cond2" + return p == "test" + } +} + +fun box(): String { + val a = A("test", "OK", "fail") + + if (a.cond1 != "cond1") return "fail 2 : ${a.cond1}" + + if (a.cond2 != "cond2") return "fail 3 : ${a.cond2}" + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/unit/kt3634.kt b/backend.native/tests/external/codegen/blackbox/unit/kt3634.kt new file mode 100644 index 00000000000..4dcbf3f5bfe --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/unit/kt3634.kt @@ -0,0 +1,8 @@ +val c = Unit +val d = c + +fun box(): String { + c + d + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/unit/kt4212.kt b/backend.native/tests/external/codegen/blackbox/unit/kt4212.kt new file mode 100644 index 00000000000..6db8f894a26 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/unit/kt4212.kt @@ -0,0 +1,23 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +fun foo(): Any? = bar() + +fun bar() {} + +fun baz(): Any? { + return bar() +} + +fun quux(): Unit? = bar() + +fun box(): String { + foo() + + if (foo() != Unit) return "Fail 1" + if (foo() != bar()) return "Fail 2" + if (bar() != baz()) return "Fail 3" + if (baz() != quux()) return "Fail 4" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/unit/kt4265.kt b/backend.native/tests/external/codegen/blackbox/unit/kt4265.kt new file mode 100644 index 00000000000..3c1aaf9d462 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/unit/kt4265.kt @@ -0,0 +1,14 @@ +fun T.let(f: (T) -> R): R = f(this) + +fun box(): String { + val o: String? = null + + var state = 0 + + o?.let { + state = 1 + } ?: ({ state = 2 })() + + if (state != 2) return "Fail: $state" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/unit/nullableUnit.kt b/backend.native/tests/external/codegen/blackbox/unit/nullableUnit.kt new file mode 100644 index 00000000000..0289cca09ba --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/unit/nullableUnit.kt @@ -0,0 +1,20 @@ +fun isNull(x: Unit?) = x == null + +fun isNullGeneric(x: T?) = x == null + +fun deepIsNull0(x: Unit?) = isNull(x) +fun deepIsNull(x: Unit?) = deepIsNull0(x) + +fun box(): String { + if (!isNull(null)) return "Fail 1" + + val x: Unit? = null + if (!isNull(x)) return "Fail 2" + + val y = x + if (!isNullGeneric(y)) return "Fail 3" + + if (!deepIsNull(x ?: null)) return "Fail 4" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/unit/nullableUnitInWhen1.kt b/backend.native/tests/external/codegen/blackbox/unit/nullableUnitInWhen1.kt new file mode 100644 index 00000000000..2d6768af748 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/unit/nullableUnitInWhen1.kt @@ -0,0 +1,12 @@ +fun foo() {} + +fun box(): String { + when ("A") { + "B" -> foo() + else -> null + } + + foo() + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/unit/nullableUnitInWhen2.kt b/backend.native/tests/external/codegen/blackbox/unit/nullableUnitInWhen2.kt new file mode 100644 index 00000000000..47807e50f19 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/unit/nullableUnitInWhen2.kt @@ -0,0 +1,12 @@ +fun foo() {} + +fun box(): String { + when ("A") { + "B" -> null + else -> foo() + } + + foo() + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/unit/nullableUnitInWhen3.kt b/backend.native/tests/external/codegen/blackbox/unit/nullableUnitInWhen3.kt new file mode 100644 index 00000000000..b2e2b0ae439 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/unit/nullableUnitInWhen3.kt @@ -0,0 +1,12 @@ +fun foo() {} + +fun box(): String { + val x = when ("A") { + "B" -> foo() + else -> null + } + + foo() + + return if (x == null) "OK" else "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/unit/unitClassObject.kt b/backend.native/tests/external/codegen/blackbox/unit/unitClassObject.kt new file mode 100644 index 00000000000..e4cdbacbe14 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/unit/unitClassObject.kt @@ -0,0 +1,11 @@ +fun box(): String { + Unit + + val a = Unit + val b = Unit + if (a != b) return "Fail a != b" + + if (Unit != Unit) return "Fail Unit != Unit" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/vararg/kt1978.kt b/backend.native/tests/external/codegen/blackbox/vararg/kt1978.kt new file mode 100644 index 00000000000..6d27ec3a311 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/vararg/kt1978.kt @@ -0,0 +1,10 @@ +fun aa(vararg a : String): String = a[0] + +fun box(): String { + var result: String = "" + var i = 1 + while (3 > i++) { + result = aa(if (true) "OK" else "fail") + } + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/vararg/kt581.kt b/backend.native/tests/external/codegen/blackbox/vararg/kt581.kt new file mode 100644 index 00000000000..829dc640f1d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/vararg/kt581.kt @@ -0,0 +1,17 @@ +package whats.the.difference + +fun iarray(vararg a : Int) = a // BUG +val IntArray.indices: IntRange get() = IntRange(0, lastIndex()) +fun IntArray.lastIndex() = size - 1 + +fun box() : String { + val vals = iarray(789, 678, 567, 456, 345, 234, 123, 12) + val diffs = HashSet() + for (i in vals.indices) + for (j in i..vals.lastIndex()) + diffs.add(vals[i] - vals[j]) + val size = diffs.size + + if (size != 8) return "Fail $size" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/vararg/kt6192.kt b/backend.native/tests/external/codegen/blackbox/vararg/kt6192.kt new file mode 100644 index 00000000000..89296cf18c2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/vararg/kt6192.kt @@ -0,0 +1,93 @@ + +fun barB(vararg args: Byte) = args +fun barC(vararg args: Char) = args +fun barD(vararg args: Double) = args +fun barF(vararg args: Float) = args +fun barI(vararg args: Int) = args +fun barJ(vararg args: Long) = args +fun barS(vararg args: Short) = args +fun barZ(vararg args: Boolean) = args + +fun sumInt(x: Int, vararg args: Int): Int { + var result = x + for(a in args) { + result += a + } + return result +} + +fun sumFunOnParameters(x: Int, vararg args: Int, f: (Int) -> Int): Int { + var result = f(x) + for(a in args) { + result += f(a) + } + return result +} + +fun concatParameters(vararg args: Int): String { + var result = "" + for(a in args) { + result += a.toString() + } + return result +} + +fun box(): String { + + val aB = ByteArray(3) + val aC = CharArray(3) + val aD = DoubleArray(3) + val aF = FloatArray(3) + val aI = IntArray(3) + aI[0] = 1 + aI[1] = 2 + aI[2] = 3 + val bI = IntArray(2) + bI[0] = 4 + bI[1] = 5 + val aJ = LongArray(3) + val aS = ShortArray(3) + val aZ = BooleanArray(3) + + + if (barB(*aB, 23.toByte()).size != 4) return "fail: Byte" + if (barB(11.toByte(), *aB, 23.toByte(), *aB).size != 8) return "fail: Byte" + + if (barC(*aC, 'A').size != 4) return "fail: Char" + if (barC('A', *aC, 'A', *aC).size != 8) return "fail: Char" + + if (barD(*aD, 2.3).size != 4) return "fail: Double" + if (barD(*aD, *aD, 2.3).size != 7) return "fail: Double" + + if (barF(*aF, 2.3f).size != 4) return "fail: Float" + if (barF(*aF, 2.3f, 1.1f).size != 5) return "fail: Float" + + if (barI(*aI, 23).size != 4) return "fail: Int" + if (barI(11, 10, *aI, 23).size != 6) return "fail: Int" + if (barI(100, *aI, *aI).size != 7) return "fail: Int 3" + + if (sumInt(100, *aI) != 106) return "fail: sumInt 1" + if (sumInt(100, *aI, 200) != 306) return "fail: sumInt 2" + if (sumInt(100, *aI, *aI) != 112) return "fail: sumInt 3" + if (sumFunOnParameters(100, *aI, 200) { 2*it } != 612) return "fail: sumFunOnParameters 1" + if (sumFunOnParameters(100, *aI, *aI) { 2*it } != 224) return "fail: sumFunOnParameters 2" + + if (concatParameters(1,2,3) != "123") return "fail: concatParameters 1" + if (concatParameters(*aI) != "123") return "fail: concatParameters 2" + if (concatParameters(4, 5, *aI) != "45123") return "fail: concatParameters 3" + if (concatParameters(*aI, 4, 5) != "12345") return "fail: concatParameters 4" + if (concatParameters(*aI, *bI) != "12345") return "fail: concatParameters 5" + if (concatParameters(*aI, 7, 8, *bI) != "1237845") return "fail: concatParameters 6" + if (concatParameters(*aI, 7, *bI, *aI, 9) != "1237451239") return "fail: concatParameters 7" + + if (barJ(*aJ, 23L).size != 4) return "fail: Long" + if (barJ(*aJ, 23L, *aJ, *aJ).size != 10) return "fail: Long" + + if (barS(*aS, 23.toShort()).size != 4) return "fail: Short" + if (barS(*aS, *aS, 23.toShort(), *aS).size != 10) return "fail: Short" + + if (barZ(*aZ, true).size != 4) return "fail: Boolean" + if (barZ(false, *aZ, true, *aZ).size != 8) return "fail: Boolean" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/vararg/kt796_797.kt b/backend.native/tests/external/codegen/blackbox/vararg/kt796_797.kt new file mode 100644 index 00000000000..ebb6be014c3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/vararg/kt796_797.kt @@ -0,0 +1,8 @@ +operator fun Array?.get(i : Int?) = this!!.get(i!!) +fun array(vararg t : T) : Array = t as Array + +fun box() : String { + val a : Array? = array("Str", "Str2") + val i : Int? = 1 + return if(a[i] == "Str2") "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/vararg/spreadCopiesArray.kt b/backend.native/tests/external/codegen/blackbox/vararg/spreadCopiesArray.kt new file mode 100644 index 00000000000..d5b7fc1fe65 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/vararg/spreadCopiesArray.kt @@ -0,0 +1,29 @@ +// WITH_RUNTIME + +import kotlin.test.* + +fun copyArray(vararg data: T): Array = data + +inline fun reifiedCopyArray(vararg data: T): Array = data + +fun copyIntArray(vararg data: Int): IntArray = data + +fun box(): String { + val sarr = arrayOf("OK") + val sarr2 = copyArray(*sarr) + sarr[0] = "Array was not copied" + assertEquals(sarr2[0], "OK", "Failed: Array") + + var rsarr = arrayOf("OK") + var rsarr2 = reifiedCopyArray(*rsarr) + rsarr[0] = "Array was not copied" + assertEquals(rsarr2[0], "OK", "Failed: Array, reified copy") + + val iarr = IntArray(1) + iarr[0] = 1 + val iarr2 = copyIntArray(*iarr) + iarr[0] = 42 + assertEquals(iarr2[0], 1, "Failed: IntArray") + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/vararg/varargInFunParam.kt b/backend.native/tests/external/codegen/blackbox/vararg/varargInFunParam.kt new file mode 100644 index 00000000000..4f5438618f2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/vararg/varargInFunParam.kt @@ -0,0 +1,69 @@ +fun box(): String { + if (test1() != "") return "fail 1" + if (test1(1) != "1") return "fail 2" + if (test1(1, 2) != "12") return "fail 3" + + if (test1(*intArrayOf()) != "") return "fail 4" + if (test1(*intArrayOf(1)) != "1") return "fail 5" + if (test1(*intArrayOf(1, 2)) != "12") return "fail 6" + + if (test1(p = 1) != "1") return "fail 7" + + if (test1(p = *intArrayOf()) != "") return "fail 8" + if (test1(p = *intArrayOf(1)) != "1") return "fail 9" + if (test1(p = *intArrayOf(1, 2)) != "12") return "fail 10" + + if (test2() != "") return "fail 11" + if (test2("1") != "1") return "fail 12" + if (test2("1", "2") != "12") return "fail 13" + + if (test2(*arrayOf()) != "") return "fail 14" + if (test2(*arrayOf("1")) != "1") return "fail 15" + if (test2(*arrayOf("1", "2")) != "12") return "fail 16" + + if (test2(p = "1") != "1") return "fail 17" + + if (test2(p = *arrayOf()) != "") return "fail 18" + if (test2(p = *arrayOf("1")) != "1") return "fail 19" + if (test2(p = *arrayOf("1", "2")) != "12") return "fail 20" + + if (test3() != "") return "fail 21" + if (test3("1") != "1") return "fail 22" + if (test3("1", "2") != "12") return "fail 23" + + if (test3(*arrayOf()) != "") return "fail 24" + if (test3(*arrayOf("1")) != "1") return "fail 25" + if (test3(*arrayOf("1", "2")) != "12") return "fail 26" + + if (test3(p = "1") != "1") return "fail 27" + + if (test3(p = *arrayOf()) != "") return "fail 28" + if (test3(p = *arrayOf("1")) != "1") return "fail 29" + if (test3(p = *arrayOf("1", "2")) != "12") return "fail 30" + + return "OK" +} + +fun test1(vararg p: Int): String { + var result = "" + for (i in p) { + result += i + } + return result +} + +fun test2(vararg p: String): String { + var result = "" + for (i in p) { + result += i + } + return result +} + +fun test3(vararg p: T): String { + var result = "" + for (i in p) { + result += i + } + return result +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/vararg/varargInJava.kt b/backend.native/tests/external/codegen/blackbox/vararg/varargInJava.kt new file mode 100644 index 00000000000..89e7e8004e6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/vararg/varargInJava.kt @@ -0,0 +1,34 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// FILE: A.java + +public class A { + public int foo(int x, String ... args) { + return x + args.length; + } + + public static String[] ar = new String[] { "a", "b"}; +} + +// FILE: test.kt + +fun bar(args: Array?): Int { + var res = 0 + + if (args != null) { + res += A().foo(1, *args) + } + + res += A().foo(1, *A.ar) + + return res +} + +fun box(): String { + if (bar(null) != 3) return "Fail" + + if (bar(A.ar) != 6) return "Fail" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/vararg/varargsAndFunctionLiterals.kt b/backend.native/tests/external/codegen/blackbox/vararg/varargsAndFunctionLiterals.kt new file mode 100644 index 00000000000..3c7dca68c44 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/vararg/varargsAndFunctionLiterals.kt @@ -0,0 +1,16 @@ +fun foo(a: Int, vararg b: Int, f: (IntArray) -> String): String { + return "test" + a + " " + f(b) +} + +fun box(): String { + val test1 = foo(1) {a -> "" + a.size} + if (test1 != "test1 0") return test1 + + val test2 = foo(2, 2) {a -> "" + a.size} + if (test2 != "test2 1") return test2 + + val test3 = foo(3, 2, 3) {a -> "" + a.size} + if (test3 != "test3 2") return test3 + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/callProperty.kt b/backend.native/tests/external/codegen/blackbox/when/callProperty.kt new file mode 100644 index 00000000000..65fc9b7997d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/callProperty.kt @@ -0,0 +1,12 @@ +class C(val p: Boolean) { } + +fun box(): String { + val c = C(true) + + // Commented for KT-621 + // return when(c) { + // .p => "OK" + // else => "fail" + // } + return if (c.p) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/emptyWhen.kt b/backend.native/tests/external/codegen/blackbox/when/emptyWhen.kt new file mode 100644 index 00000000000..62ab58b6bf3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/emptyWhen.kt @@ -0,0 +1,7 @@ +enum class A { X1, X2 } + +fun box(): String { + when {} + when (A.X1) {} + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/enumOptimization/bigEnum.kt b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/bigEnum.kt new file mode 100644 index 00000000000..fb76910b59d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/bigEnum.kt @@ -0,0 +1,52 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +enum class BigEnum { + ITEM1, ITEM2, ITEM3, ITEM4, ITEM5, ITEM6, ITEM7, ITEM8, ITEM9, ITEM10, + ITEM11, ITEM12, ITEM13, ITEM14, ITEM15, ITEM16, ITEM17, ITEM18, ITEM19, ITEM20 +} + +fun bar1(x : BigEnum) : String { + when (x) { + BigEnum.ITEM1, BigEnum.ITEM2, BigEnum.ITEM3 -> return "123" + BigEnum.ITEM4, BigEnum.ITEM5, BigEnum.ITEM6 -> return "456" + } + + return "-1"; + +} + +fun bar2(x : BigEnum) : String { + when (x) { + BigEnum.ITEM7, BigEnum.ITEM8, BigEnum.ITEM9 -> return "789" + BigEnum.ITEM10 -> return "10" + BigEnum.ITEM11, BigEnum.ITEM12 -> return "1112" + else -> return "-1" + } +} + +fun box() : String { + //bar1 + assertEquals("123", bar1(BigEnum.ITEM1)) + assertEquals("123", bar1(BigEnum.ITEM2)) + assertEquals("123", bar1(BigEnum.ITEM3)) + + assertEquals("456", bar1(BigEnum.ITEM4)) + assertEquals("456", bar1(BigEnum.ITEM5)) + assertEquals("456", bar1(BigEnum.ITEM6)) + + assertEquals("-1", bar1(BigEnum.ITEM7)) + + //bar2 + assertEquals("789", bar2(BigEnum.ITEM7)) + assertEquals("789", bar2(BigEnum.ITEM8)) + assertEquals("789", bar2(BigEnum.ITEM9)) + + assertEquals("10", bar2(BigEnum.ITEM10)) + + assertEquals("1112", bar2(BigEnum.ITEM11)) + assertEquals("1112", bar2(BigEnum.ITEM12)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/enumOptimization/duplicatingItems.kt b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/duplicatingItems.kt new file mode 100644 index 00000000000..2760d6daa88 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/duplicatingItems.kt @@ -0,0 +1,27 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +enum class Season { + WINTER, + SPRING, + SUMMER, + AUTUMN +} + +fun bar(x : Season) : String { + when (x) { + Season.WINTER, Season.SPRING -> return "winter_spring" + Season.SUMMER, Season.SPRING -> return "summer" + else -> return "autumn" + } +} + +fun box() : String { + assertEquals("winter_spring", bar(Season.WINTER)) + assertEquals("winter_spring", bar(Season.SPRING)) + assertEquals("summer", bar(Season.SUMMER)) + assertEquals("autumn", bar(Season.AUTUMN)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/enumOptimization/enumInsideClassObject.kt b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/enumInsideClassObject.kt new file mode 100644 index 00000000000..18131fed078 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/enumInsideClassObject.kt @@ -0,0 +1,31 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +class A { + companion object { + enum class Season { + WINTER, + SPRING, + SUMMER, + AUTUMN + } + } +} + +fun foo(x : A.Companion.Season) : String { + return when (x) { + A.Companion.Season.WINTER -> "winter" + A.Companion.Season.SPRING -> "spring" + A.Companion.Season.SUMMER -> "summer" + else -> "other" + } +} + +fun box() : String { + assertEquals("winter", foo(A.Companion.Season.WINTER)) + assertEquals("spring", foo(A.Companion.Season.SPRING)) + assertEquals("summer", foo(A.Companion.Season.SUMMER)) + assertEquals("other", foo(A.Companion.Season.AUTUMN)) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/enumOptimization/expression.kt b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/expression.kt new file mode 100644 index 00000000000..e1774794dea --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/expression.kt @@ -0,0 +1,39 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +enum class Season { + WINTER, + SPRING, + SUMMER, + AUTUMN +} + +fun bar1(x : Season) : String { + return when (x) { + Season.WINTER, Season.SPRING -> "winter_spring" + Season.SUMMER -> "summer" + else -> "autumn" + } +} + +fun bar2(x : Season) : String { + return when (x) { + Season.WINTER, Season.SPRING -> "winter_spring" + Season.SUMMER -> "summer" + Season.AUTUMN -> "autumn" + } +} + +fun box() : String { + assertEquals("winter_spring", bar1(Season.WINTER)) + assertEquals("winter_spring", bar1(Season.SPRING)) + assertEquals("summer", bar1(Season.SUMMER)) + assertEquals("autumn", bar1(Season.AUTUMN)) + + assertEquals("winter_spring", bar2(Season.WINTER)) + assertEquals("winter_spring", bar2(Season.SPRING)) + assertEquals("summer", bar2(Season.SUMMER)) + assertEquals("autumn", bar2(Season.AUTUMN)) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/enumOptimization/functionLiteralInTopLevel.kt b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/functionLiteralInTopLevel.kt new file mode 100644 index 00000000000..9b97152b2f3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/functionLiteralInTopLevel.kt @@ -0,0 +1,17 @@ +enum class Season { + WINTER, + SPRING, + SUMMER, + AUTUMN +} + +fun foo(x : Season, block : (Season) -> String) = block(x) + +fun box() : String { + return foo(Season.SPRING) { + x -> when (x) { + Season.SPRING -> "OK" + else -> "fail" + } + } +} diff --git a/backend.native/tests/external/codegen/blackbox/when/enumOptimization/manyWhensWithinClass.kt b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/manyWhensWithinClass.kt new file mode 100644 index 00000000000..3a29f080cb3 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/manyWhensWithinClass.kt @@ -0,0 +1,52 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +enum class Season { + WINTER, + SPRING, + SUMMER, + AUTUMN +} + +class A { + public fun bar1(x : Season) : String { + when (x) { + Season.WINTER, Season.SPRING -> return "winter_spring" + Season.SPRING -> return "spring" + Season.SUMMER -> return "summer" + } + + return "autumn"; + } + + public fun bar2(y : Season) : String { + return bar3(y) { x -> + when (x) { + Season.WINTER, Season.SPRING -> "winter_spring" + Season.SPRING -> "spring" + Season.SUMMER -> "summer" + else -> "autumn" + } + } + } + + private fun bar3(x : Season, block : (Season) -> String) = block(x) +} + +fun box() : String { + val a = A() + + assertEquals("winter_spring", a.bar1(Season.WINTER)) + assertEquals("winter_spring", a.bar1(Season.SPRING)) + assertEquals("summer", a.bar1(Season.SUMMER)) + assertEquals("autumn", a.bar1(Season.AUTUMN)) + + assertEquals("winter_spring", a.bar2(Season.WINTER)) + assertEquals("winter_spring", a.bar2(Season.SPRING)) + assertEquals("summer", a.bar2(Season.SUMMER)) + assertEquals("autumn", a.bar2(Season.AUTUMN)) + + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/enumOptimization/nonConstantEnum.kt b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/nonConstantEnum.kt new file mode 100644 index 00000000000..a1440b4712b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/nonConstantEnum.kt @@ -0,0 +1,16 @@ +enum class Season { + WINTER, + SPRING, + SUMMER, + AUTUMN +} + +fun foo(): Season = Season.SPRING +fun bar(): Season = Season.SPRING + +fun box() : String { + when (foo()) { + bar() -> return "OK" + else -> return "fail" + } +} diff --git a/backend.native/tests/external/codegen/blackbox/when/enumOptimization/nullability.kt b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/nullability.kt new file mode 100644 index 00000000000..d8734f77526 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/nullability.kt @@ -0,0 +1,42 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +enum class Season { + WINTER, + SPRING, + SUMMER, + AUTUMN +} + +fun foo1(x : Season?) : String { + when(x) { + Season.AUTUMN, Season.SPRING -> return "autumn_or_spring"; + Season.SUMMER, null -> return "summer_or_null" + } + + return "other" +} + +fun foo2(x : Season?) : String { + when(x) { + Season.AUTUMN, Season.SPRING -> return "autumn_or_spring"; + Season.SUMMER -> return "summer" + } + + return "other" +} + +fun box() : String { + assertEquals("autumn_or_spring", foo1(Season.AUTUMN)) + assertEquals("autumn_or_spring", foo1(Season.SPRING)) + assertEquals("summer_or_null", foo1(Season.SUMMER)) + assertEquals("summer_or_null", foo1(null)) + + assertEquals("autumn_or_spring", foo2(Season.AUTUMN)) + assertEquals("autumn_or_spring", foo2(Season.SPRING)) + assertEquals("summer", foo2(Season.SUMMER)) + assertEquals("other", foo2(null)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/enumOptimization/nullableEnum.kt b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/nullableEnum.kt new file mode 100644 index 00000000000..457f6281e1e --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/nullableEnum.kt @@ -0,0 +1,14 @@ +enum class E { + A, + B +} + +fun test(e: E?) = when (e) { + E.A -> "Fail A" + null -> "OK" + E.B -> "Fail B" +} + +fun box(): String { + return test(null) +} diff --git a/backend.native/tests/external/codegen/blackbox/when/enumOptimization/subjectAny.kt b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/subjectAny.kt new file mode 100644 index 00000000000..0f21003c5f6 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/subjectAny.kt @@ -0,0 +1,28 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +enum class Season { + WINTER, + SPRING, + SUMMER, + AUTUMN +} + +fun foo(x : Any) : String { + return when (x) { + Season.WINTER -> "winter" + Season.SPRING -> "spring" + Season.SUMMER -> "summer" + else -> "other" + } +} + +fun box() : String { + assertEquals("winter", foo(Season.WINTER)) + assertEquals("spring", foo(Season.SPRING)) + assertEquals("summer", foo(Season.SUMMER)) + assertEquals("other", foo(Season.AUTUMN)) + assertEquals("other", foo(123)) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/enumOptimization/withoutElse.kt b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/withoutElse.kt new file mode 100644 index 00000000000..abaea695949 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/enumOptimization/withoutElse.kt @@ -0,0 +1,43 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +enum class Season { + WINTER, + SPRING, + SUMMER, + AUTUMN +} + +fun bar1(x : Season) : String { + when (x) { + Season.WINTER, Season.SPRING -> return "winter_spring" + Season.SPRING -> return "spring" + Season.SUMMER -> return "summer" + } + return "autumn" +} + +fun bar2(x : Season) : String { + when (x) { + Season.WINTER, Season.SPRING -> return "winter_spring" + Season.SPRING -> return "spring" + Season.SUMMER -> return "summer" + Season.AUTUMN -> return "autumn" + } + + return "fail unknown" +} + +fun box() : String { + assertEquals("winter_spring", bar1(Season.WINTER)) + assertEquals("winter_spring", bar1(Season.SPRING)) + assertEquals("summer", bar1(Season.SUMMER)) + assertEquals("autumn", bar1(Season.AUTUMN)) + + assertEquals("winter_spring", bar2(Season.WINTER)) + assertEquals("winter_spring", bar2(Season.SPRING)) + assertEquals("summer", bar2(Season.SUMMER)) + assertEquals("autumn", bar2(Season.AUTUMN)) + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/exceptionOnNoMatch.kt b/backend.native/tests/external/codegen/blackbox/when/exceptionOnNoMatch.kt new file mode 100644 index 00000000000..15a1b759082 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/exceptionOnNoMatch.kt @@ -0,0 +1,14 @@ +fun isZero(x: Int) = when(x) { + 0 -> true + else -> throw Exception() +} + +fun box(): String { + try { + isZero(1) + } + catch (e: Exception) { + return "OK" + } + return "Fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/exhaustiveBoolean.kt b/backend.native/tests/external/codegen/blackbox/when/exhaustiveBoolean.kt new file mode 100644 index 00000000000..4ac2633da11 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/exhaustiveBoolean.kt @@ -0,0 +1,4 @@ +fun box() : String = when (true) { + ((true)) -> "OK" + (1 == 2) -> "Not ok" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/exhaustiveBreakContinue.kt b/backend.native/tests/external/codegen/blackbox/when/exhaustiveBreakContinue.kt new file mode 100644 index 00000000000..69c959e13cb --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/exhaustiveBreakContinue.kt @@ -0,0 +1,14 @@ +enum class Color { RED, GREEN, BLUE } + +fun foo(arr: Array): Color { + loop@ for (color in arr) { + when (color) { + Color.RED -> return color + Color.GREEN -> break@loop + Color.BLUE -> if (arr.size == 1) return color else continue@loop + } + } + return Color.GREEN +} + +fun box() = if (foo(arrayOf(Color.BLUE, Color.GREEN)) == Color.GREEN) "OK" else "FAIL" \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/when/exhaustiveWhenInitialization.kt b/backend.native/tests/external/codegen/blackbox/when/exhaustiveWhenInitialization.kt new file mode 100644 index 00000000000..ccf67614e6c --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/exhaustiveWhenInitialization.kt @@ -0,0 +1,10 @@ +enum class A { V } + +fun box(): String { + val a: A = A.V + val b: Boolean + when (a) { + A.V -> b = true + } + return if (b) "OK" else "FAIL" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/when/exhaustiveWhenReturn.kt b/backend.native/tests/external/codegen/blackbox/when/exhaustiveWhenReturn.kt new file mode 100644 index 00000000000..6b3b7658cc2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/exhaustiveWhenReturn.kt @@ -0,0 +1,8 @@ +enum class A { V } + +fun box(): String { + val a: A = A.V + when (a) { + A.V -> return "OK" + } +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/when/implicitExhaustiveAndReturn.kt b/backend.native/tests/external/codegen/blackbox/when/implicitExhaustiveAndReturn.kt new file mode 100644 index 00000000000..d28e7064678 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/implicitExhaustiveAndReturn.kt @@ -0,0 +1,9 @@ +fun test(i: Int): String { + when (i) { + 0 -> return "0" + 1 -> return "1" + } + return "OK" +} + +fun box(): String = test(42) \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/when/integralWhenWithNoInlinedConstants.kt b/backend.native/tests/external/codegen/blackbox/when/integralWhenWithNoInlinedConstants.kt new file mode 100644 index 00000000000..4b58f875147 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/integralWhenWithNoInlinedConstants.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +fun foo1(x: Int): Boolean { + when(x) { + 2 + 2 -> return true + else -> return false + } +} + +fun foo2(x: Int): Boolean { + when(x) { + Integer.MAX_VALUE -> return true + else -> return false + } +} + +fun box(): String { + assert(foo1(4)) + assert(!foo1(1)) + + assert(foo2(Integer.MAX_VALUE)) + assert(!foo2(1)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/is.kt b/backend.native/tests/external/codegen/blackbox/when/is.kt new file mode 100644 index 00000000000..fa0580b2740 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/is.kt @@ -0,0 +1,11 @@ +fun typeName(a: Any?) : String { + return when(a) { + is ArrayList<*> -> "array list" + else -> "no idea" + } +} + +fun box() : String { + if(typeName(ArrayList()) != "array list") return "array list failed" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/kt2457.kt b/backend.native/tests/external/codegen/blackbox/when/kt2457.kt new file mode 100644 index 00000000000..e6f15becd08 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/kt2457.kt @@ -0,0 +1,8 @@ +fun foo(i: Int) : Int = + when (i) { + 1 -> 1 + null -> 1 + else -> 1 + } + +fun box() : String = if (foo(1) == 1) "OK" else "fail" diff --git a/backend.native/tests/external/codegen/blackbox/when/kt2466.kt b/backend.native/tests/external/codegen/blackbox/when/kt2466.kt new file mode 100644 index 00000000000..ba2e7dd052a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/kt2466.kt @@ -0,0 +1,9 @@ +fun foo(b: Boolean) = + when (b) { + false -> 0 + true -> 1 + else -> 2 + } + +fun box(): String = if (foo(false) == 0 && foo(true) == 1) "OK" else "Fail" + diff --git a/backend.native/tests/external/codegen/blackbox/when/kt5307.kt b/backend.native/tests/external/codegen/blackbox/when/kt5307.kt new file mode 100644 index 00000000000..bbbbc8611c4 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/kt5307.kt @@ -0,0 +1,11 @@ +fun box(): String { + val value = 1 + when (value) { + 0 -> {} + 1 -> when (value) { + 2 -> false + } + } + + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/when/kt5448.kt b/backend.native/tests/external/codegen/blackbox/when/kt5448.kt new file mode 100644 index 00000000000..e1c81b55ca9 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/kt5448.kt @@ -0,0 +1,22 @@ +// WITH_RUNTIME + +class A + +class B(val items: Collection) + +class C { + fun foo(p: Int) { + when (p) { + 1 -> arrayListOf().add(1) + } + } + + fun bar() = B(listOf().map { it }) +} + +fun box(): String { + C().foo(1) + if (C().bar().items.isNotEmpty()) return "fail" + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/longInRange.kt b/backend.native/tests/external/codegen/blackbox/when/longInRange.kt new file mode 100644 index 00000000000..c73169ff600 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/longInRange.kt @@ -0,0 +1,9 @@ +class LongR { + operator fun contains(l : Long): Boolean = l == 5.toLong() +} + +fun box(): String { + if (5 !in LongR()) return "fail 1" + if (6 in LongR()) return "fail 2" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/matchNotNullAgainstNullable.kt b/backend.native/tests/external/codegen/blackbox/when/matchNotNullAgainstNullable.kt new file mode 100644 index 00000000000..c0598674113 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/matchNotNullAgainstNullable.kt @@ -0,0 +1,7 @@ +fun foo(i: Int, j: Int?): String = + when (i) { + j -> "OK" + else -> "Fail" + } + +fun box(): String = foo(0, 0) diff --git a/backend.native/tests/external/codegen/blackbox/when/multipleEntries.kt b/backend.native/tests/external/codegen/blackbox/when/multipleEntries.kt new file mode 100644 index 00000000000..65c20b334d2 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/multipleEntries.kt @@ -0,0 +1,12 @@ +fun foo(x: Any) = + when (x) { + 0, 1 -> "bit" + else -> "something" + } + +fun box(): String { + if (foo(0) != "bit") return "Fail 0" + if (foo(1) != "bit") return "Fail 1" + if (foo(2) != "something") return "Fail 2" + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/noElseExhaustive.kt b/backend.native/tests/external/codegen/blackbox/when/noElseExhaustive.kt new file mode 100644 index 00000000000..e02125f19c8 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/noElseExhaustive.kt @@ -0,0 +1,9 @@ +enum class En { + A, + B +} + +fun box(): String = when(En.A) { + En.A -> "OK" + En.B -> "Fail 1" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/when/noElseExhaustiveStatement.kt b/backend.native/tests/external/codegen/blackbox/when/noElseExhaustiveStatement.kt new file mode 100644 index 00000000000..da79d180335 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/noElseExhaustiveStatement.kt @@ -0,0 +1,12 @@ +enum class En { + A, + B +} + +fun box(): String { + when(En.A) { + En.A -> "s1" + En.B -> "s2" + } + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/when/noElseExhaustiveUnitExpected.kt b/backend.native/tests/external/codegen/blackbox/when/noElseExhaustiveUnitExpected.kt new file mode 100644 index 00000000000..2c69069abac --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/noElseExhaustiveUnitExpected.kt @@ -0,0 +1,14 @@ +enum class En { + A, + B +} + +fun box(): String { + + val u: Unit = when(En.A) { + En.A -> {} + En.B -> {} + } + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/noElseInStatement.kt b/backend.native/tests/external/codegen/blackbox/when/noElseInStatement.kt new file mode 100644 index 00000000000..9ab1c3fef63 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/noElseInStatement.kt @@ -0,0 +1,7 @@ +fun box(): String { + val x = 1 + when (x) { + 1 -> return "OK" + } + return "Fail 1" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/when/noElseNoMatch.kt b/backend.native/tests/external/codegen/blackbox/when/noElseNoMatch.kt new file mode 100644 index 00000000000..2c4e803b07b --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/noElseNoMatch.kt @@ -0,0 +1,8 @@ +fun box(): String { + val x = 3 + when (x) { + 1 -> {} + 2 -> {} + } + return "OK" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/when/nullableWhen.kt b/backend.native/tests/external/codegen/blackbox/when/nullableWhen.kt new file mode 100644 index 00000000000..717b6a9c303 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/nullableWhen.kt @@ -0,0 +1,13 @@ +// KT-2148 + + +fun f(p: Int?): Int { + return when(p) { + null -> 3 + else -> p!! + } +} + +fun box(): String { + return if (f(null) == 3) "OK" else "fail" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/range.kt b/backend.native/tests/external/codegen/blackbox/when/range.kt new file mode 100644 index 00000000000..a8d8c41c144 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/range.kt @@ -0,0 +1,29 @@ +fun isDigit(a: Int) : String { + val aa = ArrayList () + aa.add(239) + + return when(a) { + in aa -> "array list" + in 0..9 -> "digit" + !in 0..100 -> "not small" + else -> "something" + } +} + +fun assertDigit(i: Int, expected: String): String { + val result = isDigit(i) + return if (result == expected) "" else "fail: isDigit($i) = \"$result\"" +} + +fun box(): String { + val result = + assertDigit(239, "array list") + + assertDigit(0, "digit") + + assertDigit(9, "digit") + + assertDigit(5, "digit") + + assertDigit(19, "something") + + assertDigit(190, "not small") + + if (result == "") return "OK" + return result +} diff --git a/backend.native/tests/external/codegen/blackbox/when/sealedWhenInitialization.kt b/backend.native/tests/external/codegen/blackbox/when/sealedWhenInitialization.kt new file mode 100644 index 00000000000..5f9db0bde7d --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/sealedWhenInitialization.kt @@ -0,0 +1,15 @@ +sealed class A { + object B : A() + + class C : A() +} + +fun box(): String { + val a: A = A.C() + val b: Boolean + when (a) { + A.B -> b = true + is A.C -> b = false + } + return if (!b) "OK" else "FAIL" +} \ No newline at end of file diff --git a/backend.native/tests/external/codegen/blackbox/when/stringOptimization/duplicatingItems.kt b/backend.native/tests/external/codegen/blackbox/when/stringOptimization/duplicatingItems.kt new file mode 100644 index 00000000000..d000aa96cfa --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/stringOptimization/duplicatingItems.kt @@ -0,0 +1,21 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun foo(x : String) : String { + when (x) { + "abc" -> return "abc" + "efg", "ghi", "abc" -> return "efg_ghi" + else -> return "other" + } +} + +fun box() : String { + assertEquals("abc", foo("abc")) + assertEquals("efg_ghi", foo("efg")) + assertEquals("efg_ghi", foo("ghi")) + + assertEquals("other", foo("xyz")) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/stringOptimization/duplicatingItemsSameHashCode.kt b/backend.native/tests/external/codegen/blackbox/when/stringOptimization/duplicatingItemsSameHashCode.kt new file mode 100644 index 00000000000..53f6754fb71 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/stringOptimization/duplicatingItemsSameHashCode.kt @@ -0,0 +1,29 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun foo(x : String) : String { + assert("abz]".hashCode() == "aby|".hashCode()) + + when (x) { + "abz]" -> return "abz" + "ghi" -> return "ghi" + "aby|" -> return "aby" + "abz]" -> return "fail" + } + + return "other" +} + +fun box() : String { + assertEquals("abz", foo("abz]")) + assertEquals("aby", foo("aby|")) + assertEquals("ghi", foo("ghi")) + + assertEquals("other", foo("xyz")) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/stringOptimization/expression.kt b/backend.native/tests/external/codegen/blackbox/when/stringOptimization/expression.kt new file mode 100644 index 00000000000..bc9759e64ee --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/stringOptimization/expression.kt @@ -0,0 +1,22 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun foo(x : String) : String { + return when (x) { + "abc", "cde" -> "abc_cde" + "efg", "ghi" -> "efg_ghi" + else -> "other" + } +} + +fun box() : String { + assertEquals("abc_cde", foo("abc")) + assertEquals("abc_cde", foo("cde")) + assertEquals("efg_ghi", foo("efg")) + assertEquals("efg_ghi", foo("ghi")) + + assertEquals("other", foo("xyz")) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/stringOptimization/nullability.kt b/backend.native/tests/external/codegen/blackbox/when/stringOptimization/nullability.kt new file mode 100644 index 00000000000..d2d047fb153 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/stringOptimization/nullability.kt @@ -0,0 +1,43 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun foo1(x : String?) : String { + when (x) { + "abc", "cde" -> return "abc_cde" + "efg", "ghi", null -> return "efg_ghi" + } + + return "other" +} + +fun foo2(x : String?) : String { + when (x) { + "abc", "cde" -> return "abc_cde" + "efg", "ghi" -> return "efg_ghi" + else -> return "other" + } +} + +fun box() : String { + //foo1 + assertEquals("abc_cde", foo1("abc")) + assertEquals("abc_cde", foo1("cde")) + assertEquals("efg_ghi", foo1("efg")) + assertEquals("efg_ghi", foo1("ghi")) + assertEquals("efg_ghi", foo1(null)) + + assertEquals("other", foo1("xyz")) + + //foo2 + assertEquals("abc_cde", foo2("abc")) + assertEquals("abc_cde", foo2("cde")) + assertEquals("efg_ghi", foo2("efg")) + assertEquals("efg_ghi", foo2("ghi")) + + + assertEquals("other", foo2("xyz")) + assertEquals("other", foo2(null)) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/stringOptimization/sameHashCode.kt b/backend.native/tests/external/codegen/blackbox/when/stringOptimization/sameHashCode.kt new file mode 100644 index 00000000000..fd4d11e6b65 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/stringOptimization/sameHashCode.kt @@ -0,0 +1,28 @@ +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun foo(x : String) : String { + assert("abz]".hashCode() == "aby|".hashCode()) + + when (x) { + "abz]", "cde" -> return "abz_cde" + "aby|", "ghi", "abz]" -> return "aby_ghi" + } + + return "other" +} + +fun box() : String { + assertEquals("abz_cde", foo("abz]")) + assertEquals("abz_cde", foo("cde")) + assertEquals("aby_ghi", foo("aby|")) + assertEquals("aby_ghi", foo("ghi")) + + assertEquals("other", foo("xyz")) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/stringOptimization/statement.kt b/backend.native/tests/external/codegen/blackbox/when/stringOptimization/statement.kt new file mode 100644 index 00000000000..4f9bdc05158 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/stringOptimization/statement.kt @@ -0,0 +1,40 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +fun foo1(x : String) : String { + when (x) { + "abc", "cde" -> return "abc_cde" + "efg", "ghi" -> return "efg_ghi" + } + + return "other" +} + +fun foo2(x : String) : String { + when (x) { + "abc", "cde" -> return "abc_cde" + "efg", "ghi" -> return "efg_ghi" + else -> return "other" + } +} + +fun box() : String { + //foo1 + assertEquals("abc_cde", foo1("abc")) + assertEquals("abc_cde", foo1("cde")) + assertEquals("efg_ghi", foo1("efg")) + assertEquals("efg_ghi", foo1("ghi")) + + assertEquals("other", foo1("xyz")) + + //foo2 + assertEquals("abc_cde", foo2("abc")) + assertEquals("abc_cde", foo2("cde")) + assertEquals("efg_ghi", foo2("efg")) + assertEquals("efg_ghi", foo2("ghi")) + + assertEquals("other", foo2("xyz")) + + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/switchOptimizationDense.kt b/backend.native/tests/external/codegen/blackbox/when/switchOptimizationDense.kt new file mode 100644 index 00000000000..3fc11852388 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/switchOptimizationDense.kt @@ -0,0 +1,24 @@ +// WITH_RUNTIME + +fun dense(x: Int): Int { + return when (x) { + -4 -> 9 + -1 -> 10 + 0 -> 11 + 1 -> 12 + 4 -> 13 + 5 -> 14 + 6 -> 15 + 7 -> 16 + 8 -> 17 + 9 -> 18 + else -> 19 + } +} + +fun box(): String { + var result = (-5..10).map(::dense).joinToString() + + if (result != "19, 9, 19, 19, 10, 11, 12, 19, 19, 13, 14, 15, 16, 17, 18, 19") return "dense:" + result + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/switchOptimizationMultipleConditions.kt b/backend.native/tests/external/codegen/blackbox/when/switchOptimizationMultipleConditions.kt new file mode 100644 index 00000000000..d9cd6fd5809 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/switchOptimizationMultipleConditions.kt @@ -0,0 +1,17 @@ +// WITH_RUNTIME + +fun foo(x: Int): Int { + return when (x) { + 1, 2, 3 -> 1 + 4, 5, 6 -> 2 + 7, 8, 9 -> 3 + else -> 4 + } +} + +fun box(): String { + var result = (0..10).map(::foo).joinToString() + + if (result != "4, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4") return result + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/switchOptimizationSparse.kt b/backend.native/tests/external/codegen/blackbox/when/switchOptimizationSparse.kt new file mode 100644 index 00000000000..35e33e80d73 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/switchOptimizationSparse.kt @@ -0,0 +1,17 @@ +// WITH_RUNTIME + +fun sparse(x: Int): Int { + return when ((x % 4) * 100) { + 100 -> 1 + 200 -> 2 + 300 -> 3 + else -> 4 + } +} + +fun box(): String { + var result = (0..3).map(::sparse).joinToString() + + if (result != "4, 1, 2, 3") return "sparse:" + result + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/switchOptimizationStatement.kt b/backend.native/tests/external/codegen/blackbox/when/switchOptimizationStatement.kt new file mode 100644 index 00000000000..2e436ca37f1 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/switchOptimizationStatement.kt @@ -0,0 +1,35 @@ +// WITH_RUNTIME + +fun exhaustive(x: Int): Int { + var r: Int + when (x) { + 1 -> r = 1 + 2 -> r = 2 + 3 -> r = 3 + else -> r = 4 + } + + return r +} + +fun nonExhaustive(x: Int): Int { + var r: Int = 4 + when (x) { + 1 -> r = 1 + 2 -> r = 2 + 3 -> r = 3 + } + + return r +} + +fun box(): String { + var result = (0..3).map(::exhaustive).joinToString() + + if (result != "4, 1, 2, 3") return "exhaustive:" + result + + result = (0..3).map(::nonExhaustive).joinToString() + + if (result != "4, 1, 2, 3") return "non-exhaustive:" + result + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/switchOptimizationTypes.kt b/backend.native/tests/external/codegen/blackbox/when/switchOptimizationTypes.kt new file mode 100644 index 00000000000..75333b05096 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/switchOptimizationTypes.kt @@ -0,0 +1,56 @@ +// WITH_RUNTIME + +fun intFoo(x: Int): Int { + return when (x) { + 1 -> 5 + 2 -> 6 + 3 -> 7 + else -> 8 + } +} + +fun shortFoo(x: Short): Int { + return when (x) { + 1.toShort() -> 5 + 2.toShort() -> 6 + 3.toShort() -> 7 + else -> 8 + } +} + +fun byteFoo(x: Byte): Int { + return when (x) { + 1.toByte() -> 5 + 2.toByte() -> 6 + 3.toByte() -> 7 + else -> 8 + } +} + +fun charFoo(x: Char): Int { + return when (x) { + 'a' -> 5 + 'b' -> 6 + 'c' -> 7 + else -> 8 + } +} + +fun box(): String { + var result = (1..4).map(::intFoo).joinToString() + + if (result != "5, 6, 7, 8") return "int:" + result + + result = (listOf(1, 2, 3, 4)).map(::shortFoo).joinToString() + + if (result != "5, 6, 7, 8") return "short:" + result + + result = (listOf(1, 2, 3, 4)).map(::byteFoo).joinToString() + + if (result != "5, 6, 7, 8") return "byte:" + result + + result = ('a'..'d').map(::charFoo).joinToString() + + if (result != "5, 6, 7, 8") return "int:" + result + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/switchOptimizationUnordered.kt b/backend.native/tests/external/codegen/blackbox/when/switchOptimizationUnordered.kt new file mode 100644 index 00000000000..e299845073a --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/switchOptimizationUnordered.kt @@ -0,0 +1,17 @@ +// WITH_RUNTIME + +fun foo(x: Int): Int { + return when (x) { + 2 -> 6 + 1 -> 5 + 3 -> 7 + else -> 8 + } +} + +fun box(): String { + var result = (0..3).map(::foo).joinToString() + + if (result != "8, 5, 6, 7") return "unordered:" + result + return "OK" +} diff --git a/backend.native/tests/external/codegen/blackbox/when/typeDisjunction.kt b/backend.native/tests/external/codegen/blackbox/when/typeDisjunction.kt new file mode 100644 index 00000000000..1d2910393b0 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/typeDisjunction.kt @@ -0,0 +1,15 @@ +fun foo(s: Any): String { + val x = when (s) { + is String -> s + is Int -> "$s" + else -> return "" + } + + val y: String = x + return y +} + +fun box() = if (foo("OK") == "OK" && foo(42) == "42" && foo(true) == "") "OK" else "Fail" + + + diff --git a/backend.native/tests/external/codegen/blackbox/when/whenArgumentIsEvaluatedOnlyOnce.kt b/backend.native/tests/external/codegen/blackbox/when/whenArgumentIsEvaluatedOnlyOnce.kt new file mode 100644 index 00000000000..48ebea48731 --- /dev/null +++ b/backend.native/tests/external/codegen/blackbox/when/whenArgumentIsEvaluatedOnlyOnce.kt @@ -0,0 +1,13 @@ +var x = 0 +fun inc(): Int { + x++ + return 0 +} +fun box(): String { + val al = ArrayList() + when (inc()) { + in al -> return "fail 1" + else -> {} + } + return if (x == 1) "OK" else "fail 2" +} diff --git a/buildSrc/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy b/buildSrc/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy new file mode 100644 index 00000000000..111dfc1ae2e --- /dev/null +++ b/buildSrc/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy @@ -0,0 +1,270 @@ +package org.jetbrains.kotlin + +import groovy.io.FileType +import org.gradle.api.DefaultTask +import org.gradle.api.internal.tasks.testing.detection.DefaultTestExecuter +import org.gradle.api.tasks.ParallelizableTask +import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.testing.Test + +abstract class KonanTest extends DefaultTask { + protected String source + def backendNative = project.project(":backend.native") + def runtimeProject = project.project(":runtime") + def dist = project.rootProject.file("dist") + def llvmLlc = llvmTool("llc") + def runtimeBc = new File("${dist.canonicalPath}/lib/runtime.bc").absolutePath + def launcherBc = new File("${dist.canonicalPath}/lib/launcher.bc").absolutePath + def startKtBc = new File("${dist.canonicalPath}/lib/start.kt.bc").absolutePath + def stdlibKtBc = new File("${dist.canonicalPath}/lib/stdlib.kt.bc").absolutePath + def mainC = 'main.c' + String goldValue = null + String testData = null + List arguments = null + + boolean enabled = true + + public void setDisabled(boolean value) { + this.enabled = !value + } + + public KonanTest(){ + // TODO: that's a long reach up the project tree. + // May be we should reorganize a little. + //dependsOn(project.parent.parent.tasks['dist']) + dependsOn(project.rootProject.tasks['dist']) + } + + abstract void compileTest(List filesToCompile, String exe) + + protected void runCompiler(List filesToCompile, String output, List moreArgs) { + def log = new ByteArrayOutputStream() + try { + project.javaexec { + main = 'org.jetbrains.kotlin.cli.bc.K2NativeKt' + classpath = project.configurations.cli_bc + jvmArgs "-ea", + "-Dkonan.home=${dist.canonicalPath}", + "-Djava.library.path=${dist.canonicalPath}/konan/nativelib" + args("-output", output, + *filesToCompile, + *moreArgs, + *project.globalArgs) + standardOutput = log + errorOutput = log + } + } finally { + def logString = log.toString() + project.file("${output}.compilation.log").write(logString) + println(logString) + } + } + + protected void runCompiler(String source, String output, List moreArgs) { + runCompiler([source], output, moreArgs) + } + + String buildExePath() { + def exeName = project.file(source).name.replace(".kt", ".kt.exe") + def tempDir = temporaryDir.absolutePath + return "$tempDir/$exeName" + } + + List buildCompileList() { + return [project.file(source).absolutePath] + } + + @TaskAction + void executeTest() { + def exe = buildExePath() + + compileTest(buildCompileList(), exe) + println "execution :$exe" + + def out = null + //TODO Add test timeout + project.exec { + commandLine exe + if (arguments != null) { + args arguments + } + if (testData != null) { + standardInput = new ByteArrayInputStream(testData.bytes) + } + if (goldValue != null) { + out = new ByteArrayOutputStream() + standardOutput = out + } + + } + if (goldValue != null && goldValue != out.toString()) + throw new RuntimeException("test failed.") + } + + private String llvmTool(String tool) { + return "${project.llvmDir}/bin/${tool}" + } + + protected List clangLinkArgs() { + return project.clangLinkArgs + } +} + +class RunKonanTest extends KonanTest { + void compileTest(List filesToCompile, String exe) { + runCompiler(filesToCompile, exe, []) + } +} + +class LinkKonanTest extends KonanTest { + protected String lib + + void compileTest(List filesToCompile, String exe) { + def libDir = project.file(lib).absolutePath + def libBc = "${libDir}.bc" + + runCompiler(lib, libBc, ['-nolink', '-nostdlib']) + runCompiler(filesToCompile, exe, ['-library', libBc]) + } +} + +@ParallelizableTask +class RunExternalTestGroup extends RunKonanTest { + + def groupDirectory = "." + def logFileName = "test-result.md" + String filter = project.findProperty("filter") + String goldValue = "OK" + + // TODO refactor + List buildCompileList() { + def result = [] + def filePattern = ~/(?m)\/\/\s*FILE:\s*(.*)$/ + def packagePattern = ~/(?m)package\s*([a-zA-z-][a-zA-Z0-9.-]*)/ //TODO check the regex + def boxPattern = ~/(?m)fun\s*box\s*\(\s*\)/ + def boxPackage = "" + def srcFile = project.file(source) + def srcText = srcFile.text + def matcher = filePattern.matcher(srcText) + def tmpDir = temporaryDir.absolutePath + + if (!matcher.find()) { + // There is only one file in the input + project.copy{ + from srcFile.absolutePath + into tmpDir + } + def newFile ="$tmpDir/${srcFile.name}" + if (srcText =~ boxPattern && srcText =~ packagePattern){ + boxPackage = (srcText =~ packagePattern)[0][1] + boxPackage += '.' + } + result.add(newFile) + } else { + // There are several files + def processedChars = 0 + while (true) { + def filePath = matcher.group(1) + filePath = "$tmpDir/$filePath" + def start = processedChars + def nextFileExists = matcher.find() + def end = nextFileExists ? matcher.start() : srcText.length() + def fileText = srcText.substring(start, end) + processedChars = end + createFile(filePath, fileText) + if (fileText =~ boxPattern && fileText =~ packagePattern){ + boxPackage = (fileText =~ packagePattern)[0][1] + boxPackage += '.' + } + result.add(filePath) + if (!nextFileExists) break + } + } + createLauncherFile("$tmpDir/_launcher.kt", boxPackage) + result.add("$tmpDir/_launcher.kt") + return result + } + + void createLauncherFile(String file, String pkg) { + createFile(file, "fun main(args : Array) { print(${pkg}box()) }") + } + + void createFile(String file, String text) { + project.file(file).write(text) + } + + List findLinesWithPrefixesRemoved(String text, String prefix) { + def result = [] + text.eachLine { + if (it.startsWith(prefix)) { + result.add(it - prefix) + } + } + return result + } + + boolean isEnabledForNativeBackend(String fileName) { + def text = project.file(fileName).text + def targetBackend = findLinesWithPrefixesRemoved(text, "// TARGET_BACKEND") + if (targetBackend.size() != 0) { + // There is some target backend. Check if it is NATIVE or not + for (String s : targetBackend) { + if (s.contains("NATIVE")){ return true } + } + return false + } else { + // No target backend. Check if NATIVE backend is ignored + def ignoredBackends = findLinesWithPrefixesRemoved(text, "// IGNORE_BACKEND: ") + for (String s : ignoredBackends) { + if (s.contains("NATIVE")) { return false } + } + return true + } + } + + @TaskAction + @Override + void executeTest() { + def logFile = project.file(logFileName) + logFile.append("\n$groupDirectory\n\n") + logFile.append("|Test|Status|Comment|\n|----|------|-------|\n") + def ktFiles = project.file(groupDirectory).listFiles(new FileFilter() { + @Override + boolean accept(File pathname) { + pathname.isFile() && pathname.name.endsWith(".kt") + } + }) + if (filter != null) { + def pattern = ~filter + ktFiles = ktFiles.findAll { + it.name =~ pattern + } + } + def current = 0 + def passed = 0 + def skipped = 0 + def total = ktFiles.size() + def status = null + def comment = null + ktFiles.each { + current++ + source = project.relativePath(it) + println("TEST: $it.name ($current/$total, passed: $passed, skipped: $skipped)") + if (isEnabledForNativeBackend(source)) { + try { + super.executeTest() + status = "PASSED"; comment = "" + passed++ + } catch (Exception ex) { + status = "FAILED"; comment = "Exception: ${ex.getMessage()}. Cause: ${ex.getCause()?.getMessage()}" + } + } else { + status = "SKIPPED"; comment = "" + skipped++ + } + println("TEST $status\n") + logFile.append("|$it.name|$status|$comment|\n") + } + println("TOTAL PASSED: $passed/$current (SKIPPED: $skipped)") + } +} diff --git a/settings.gradle b/settings.gradle index a4cb6759f92..de284fb5fbb 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,3 +7,4 @@ include ':backend.native' include ':runtime' include ':common' include ':backend.native:tests' +include ':backend.native:tests:external'