Enable JS IR backend (#1832)

* Enable JS IR backend
* Workaround resolving Gradle metadata in kotlin2js plugin

Co-authored-by: Vsevolod Tolstopyatov <qwwdfsad@gmail.com>
diff --git a/gradle.properties b/gradle.properties
index 53a8de2..b11fef0 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -29,6 +29,7 @@
 baksmali_version=2.2.7
 
 # JS
+kotlin.js.compiler=both
 gradle_node_version=1.2.0
 node_version=8.9.3
 npm_version=5.7.1
@@ -43,3 +44,7 @@
 
 # Site deneration
 jekyll_version=4.0
+
+# JS IR baceknd sometimes crashes with out-of-memory
+# TODO: Remove once KT-37187 is fixed
+org.gradle.jvmargs=-Xmx2g
\ No newline at end of file
diff --git a/gradle/compile-js-multiplatform.gradle b/gradle/compile-js-multiplatform.gradle
index a7da5c6..e09e8e2 100644
--- a/gradle/compile-js-multiplatform.gradle
+++ b/gradle/compile-js-multiplatform.gradle
@@ -6,7 +6,16 @@
 
 kotlin {
     targets {
-        fromPreset(presets.js, 'js')
+        fromPreset(presets.js, 'js') {
+            // Enable built-in test runner only for IR target.
+            // These runners don't support changing js module name change.
+            if (js.hasProperty("irTarget")) {
+                irTarget.nodejs()
+                irTarget?.compilations['main']?.dependencies {
+                    api "org.jetbrains.kotlinx:atomicfu-js:$atomicfu_version"
+                }
+            }
+        }
     }
 
     sourceSets {
@@ -41,12 +50,16 @@
     kotlinOptions.moduleKind = 'umd'
 }
 
+
 task populateNodeModules(type: Copy, dependsOn: compileTestKotlinJs) {
     // we must copy output that is transformed by atomicfu
     from(kotlin.targets.js.compilations.main.output.allOutputs)
     into "$node.nodeModulesDir/node_modules"
 
-    def configuration = configurations.jsTestRuntimeClasspath
+    def configuration = configurations.hasProperty("legacyjsTestRuntimeClasspath")
+            ? configurations.legacyjsTestRuntimeClasspath
+            : configurations.jsTestRuntimeClasspath
+
     from(files {
         configuration.collect { File file ->
             file.name.endsWith(".jar") ?
diff --git a/gradle/publish-bintray.gradle b/gradle/publish-bintray.gradle
index c8dd8f1..d4bbe69 100644
--- a/gradle/publish-bintray.gradle
+++ b/gradle/publish-bintray.gradle
@@ -89,8 +89,8 @@
                 break
         }
 
-        // disable metadata everywhere, but in native modules
-        if (type == 'maven' || type == 'metadata' || type == 'jvm' || type == 'js') {
+        // disable metadata everywhere, but in native and js modules
+        if (type == 'maven' || type == 'metadata' || type == 'jvm') {
             moduleDescriptorGenerator = null
         }
     }
diff --git a/gradle/test-mocha-js.gradle b/gradle/test-mocha-js.gradle
index 464898e..60969f9 100644
--- a/gradle/test-mocha-js.gradle
+++ b/gradle/test-mocha-js.gradle
@@ -19,7 +19,9 @@
     if (project.hasProperty("teamcity")) args += ['--reporter', 'mocha-teamcity-reporter']
 }
 
-jsTest.dependsOn testMochaNode
+def legacyjsTestTask = project.tasks.findByName('legacyjsTest') ? legacyjsTest : jsTest
+
+legacyjsTestTask.dependsOn testMochaNode
 
 // -- Testing with Mocha under headless Chrome
 
@@ -89,5 +91,5 @@
     if (project.hasProperty("teamcity")) args += ['--reporter', 'mocha-teamcity-reporter']
 }
 
-jsTest.dependsOn testMochaJsdom
+legacyjsTestTask.dependsOn testMochaJsdom
 
diff --git a/js/example-frontend-js/build.gradle b/js/example-frontend-js/build.gradle
index ff62455..dc4dfd2 100644
--- a/js/example-frontend-js/build.gradle
+++ b/js/example-frontend-js/build.gradle
@@ -5,6 +5,24 @@
 apply plugin: 'kotlin-dce-js'
 apply from: rootProject.file('gradle/node-js.gradle')
 
+// Workaround resolving new Gradle metadata with kotlin2js
+// TODO: Remove once KT-37188 is fixed
+try {
+    def jsCompilerType = Class.forName("org.jetbrains.kotlin.gradle.targets.js.JsCompilerType")
+    def jsCompilerAttr = Attribute.of("org.jetbrains.kotlin.js.compiler", jsCompilerType)
+    project.dependencies.attributesSchema.attribute(jsCompilerAttr)
+    configurations {
+        matching {
+            it.name.endsWith("Classpath")
+        }.forEach {
+            it.attributes.attribute(jsCompilerAttr, jsCompilerType.legacy)
+        }
+    }
+} catch (java.lang.ClassNotFoundException e) {
+    // org.jetbrains.kotlin.gradle.targets.js.JsCompilerType is missing in 1.3.x
+    // But 1.3.x doesn't generate Gradle metadata, so this workaround is not needed
+}
+
 dependencies {
     compile "org.jetbrains.kotlinx:kotlinx-html-js:$html_version"
 }