JS: error message (not exception) for incompatible abi version during compilation

This commit is contained in:
Michael Nedzelsky
2015-06-05 13:29:20 +03:00
parent 34577a7e12
commit 999c83240c
10 changed files with 73 additions and 28 deletions
+6
View File
@@ -0,0 +1,6 @@
$TESTDATA_DIR$/simple2js.kt
-no-stdlib
-library-files
$TESTDATA_DIR$/wrongAbiVersionLib/wrongAbiLib.meta.js
-output
$TEMP_DIR$/out.js
+2
View File
@@ -0,0 +1,2 @@
ERROR: File 'compiler/testData/cli/js/wrongAbiVersionLib/wrongAbiLib.meta.js' was compiled with an incompatible version of Kotlin. Its ABI version is 0, expected ABI version is 3
COMPILATION_ERROR
@@ -0,0 +1 @@
// Kotlin.kotlin_module_metadata(0, "wrongAbiLib", "");
@@ -285,5 +285,11 @@ public class KotlincExecutableTestGenerated extends AbstractKotlincExecutableTes
String fileName = JetTestUtils.navigationMetadata("compiler/testData/cli/js/withLib.args");
doJsTest(fileName);
}
@TestMetadata("wrongAbiVersion.args")
public void testWrongAbiVersion() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/cli/js/wrongAbiVersion.args");
doJsTest(fileName);
}
}
}
@@ -51,6 +51,13 @@ public class K2JsCliTest extends CliBaseTest {
Assert.assertFalse(new File(tmpdir.getTmpDir(), "out.js").exists());
}
@Test
public void wrongAbiVersion() throws Exception {
executeCompilerCompareOutputJS();
Assert.assertFalse(new File(tmpdir.getTmpDir(), "out.js").exists());
}
@Test
public void jsHelp() throws Exception {
executeCompilerCompareOutputJS();
@@ -16,35 +16,46 @@
package org.jetbrains.kotlin.utils
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.util.io.FileUtil
import java.io.File
import java.io.IOException
import javax.xml.bind.DatatypeConverter.parseBase64Binary
import javax.xml.bind.DatatypeConverter.printBase64Binary
import kotlin.platform.platformStatic
public class KotlinJavascriptMetadata(public val moduleName: String, public val body: ByteArray)
public class KotlinJavascriptMetadata(public val abiVersion: Int, public val moduleName: String, public val body: ByteArray) {
public val isAbiVersionCompatible: Boolean = KotlinJavascriptMetadataUtils.isAbiVersionCompatible(abiVersion)
}
public object KotlinJavascriptMetadataUtils {
private val LOG = Logger.getInstance(javaClass<KotlinJavascriptMetadataUtils>())
public val JS_EXT: String = ".js"
public val META_JS_SUFFIX: String = ".meta.js"
public val VFS_PROTOCOL: String = "kotlin-js-meta"
private val KOTLIN_JAVASCRIPT_METHOD_NAME = "kotlin_module_metadata"
private val KOTLIN_JAVASCRIPT_METHOD_NAME_PATTERN = "\\.kotlin_module_metadata\\(".toRegex()
private val KOTLIN_JAVASCRIPT_METHOD_NAME_PATTERN = "\\.kotlin_module_metadata\\(".toPattern()
/**
* Matches string like <name>.kotlin_module_metadata(<abi version>, <module name>, <base64 data>)
*/
private val METADATA_PATTERN = "(?m)\\w+\\.$KOTLIN_JAVASCRIPT_METHOD_NAME\\((\\d+),\\s*(['\"])([^'\"]*)\\2,\\s*(['\"])([^'\"]*)\\4\\)".toRegex()
private val ABI_VERSION = 3
private val METADATA_PATTERN = "(?m)\\w+\\.$KOTLIN_JAVASCRIPT_METHOD_NAME\\((\\d+),\\s*(['\"])([^'\"]*)\\2,\\s*(['\"])([^'\"]*)\\4\\)".toPattern()
platformStatic
public val ABI_VERSION: Int = 3
public fun replaceSuffix(filePath: String): String = filePath.substringBeforeLast(JS_EXT) + META_JS_SUFFIX
platformStatic
public fun isAbiVersionCompatible(abiVersion: Int): Boolean = abiVersion == ABI_VERSION
platformStatic
public fun hasMetadata(text: String): Boolean = METADATA_PATTERN.matcher(text).find()
public fun hasMetadataWithIncompatibleAbiVersion(text: String): Boolean {
val matcher = METADATA_PATTERN.matcher(text)
while (matcher.find()) {
var abiVersion = matcher.group(1).toInt()
if (abiVersion != ABI_VERSION) return true
}
return false
}
public fun formatMetadataAsString(moduleName: String, content: ByteArray): String =
"// Kotlin.$KOTLIN_JAVASCRIPT_METHOD_NAME($ABI_VERSION, \"$moduleName\", \"${printBase64Binary(content)}\");\n"
@@ -59,7 +70,7 @@ public object KotlinJavascriptMetadataUtils {
path += "/$relativePath"
}
parseMetadata(content, path, metadataList)
parseMetadata(content, metadataList)
}
return metadataList
@@ -68,18 +79,17 @@ public object KotlinJavascriptMetadataUtils {
platformStatic
public fun loadMetadata(path: String): List<KotlinJavascriptMetadata> = loadMetadata(File(path))
private fun parseMetadata(text: String, path: String, metadataList: MutableList<KotlinJavascriptMetadata>) {
platformStatic
public fun parseMetadata(text: String, metadataList: MutableList<KotlinJavascriptMetadata>) {
// Check for literal pattern first in order to reduce time for large files without metadata
if (!KOTLIN_JAVASCRIPT_METHOD_NAME_PATTERN.matcher(text).find()) return
val matcher = METADATA_PATTERN.matcher(text)
while (matcher.find()) {
var abiVersion = Integer.parseInt(matcher.group(1));
if (abiVersion != ABI_VERSION) LOG.error("Unsupported abi version in $path, expected $ABI_VERSION, but $abiVersion")
var abiVersion = matcher.group(1).toInt()
var moduleName = matcher.group(3)
val data = matcher.group(5)
metadataList.add(KotlinJavascriptMetadata(moduleName, parseBase64Binary(data)))
metadataList.add(KotlinJavascriptMetadata(abiVersion, moduleName, parseBase64Binary(data)))
}
}
}