Speed-up looking up modules in JS files. This reduces the time needed for JS backend tests to pass

(cherry picked from commit 951ec82)
This commit is contained in:
Alexey Andreev
2016-03-26 17:11:15 +03:00
parent b3698b1177
commit 20c0f62d8b
@@ -43,6 +43,7 @@ import java.io.File
* Kotlin, _ can be renamed by minifier, quotes type can be changed too (" to ')
*/
private val DEFINE_MODULE_PATTERN = "(\\w+)\\.defineModule\\(\\s*(['\"])(\\w+)\\2\\s*,\\s*(\\w+)\\s*\\)".toRegex()
private val DEFINE_MODULE_FIND_PATTERN = ".defineModule("
class FunctionReader(private val context: TranslationContext) {
/**
@@ -68,12 +69,20 @@ class FunctionReader(private val context: TranslationContext) {
val libs = config.libraries.map { File(it) }
JsLibraryUtils.traverseJsLibraries(libs) { fileContent, path ->
val matcher = DEFINE_MODULE_PATTERN.toPattern().matcher(fileContent)
var current = 0
while (matcher.find()) {
val moduleName = matcher.group(3)
val moduleVariable = matcher.group(4)
val kotlinVariable = matcher.group(1)
while (true) {
var index = fileContent.indexOf(DEFINE_MODULE_FIND_PATTERN, current)
if (index < 0) break
current = index + 1
index = rewindToFirstAlpha(fileContent, index)
val preciseMatcher = DEFINE_MODULE_PATTERN.toPattern().matcher(offset(fileContent, index))
if (!preciseMatcher.lookingAt()) continue
val moduleName = preciseMatcher.group(3)
val moduleVariable = preciseMatcher.group(4)
val kotlinVariable = preciseMatcher.group(1)
assert(moduleName !in moduleJsDefinition) { "Module is defined in more, than one file" }
moduleJsDefinition[moduleName] = fileContent
moduleRootVariable[moduleName] = moduleVariable
@@ -82,6 +91,32 @@ class FunctionReader(private val context: TranslationContext) {
}
}
private fun rewindToFirstAlpha(text: String, index: Int): Int {
var result = index
while (result > 0 && isAlphaNum(text[result - 1])) {
--result
}
return result
}
private fun offset(text: String, offset: Int) = object : CharSequence {
override val length: Int
get() = text.length - offset
override fun get(index: Int) = text[index + offset]
override fun subSequence(startIndex: Int, endIndex: Int) = text.subSequence(startIndex + offset, endIndex + offset)
override fun toString() = text.substring(offset)
}
private fun isAlphaNum(c: Char) = when (c) {
in 'A'..'Z',
in 'a'..'z',
in '0'..'9' -> true
else -> false
}
private val functionCache = object : SLRUCache<CallableDescriptor, JsFunction>(50, 50) {
override fun createValue(descriptor: CallableDescriptor): JsFunction =
readFunction(descriptor).sure { "Could not read function: $descriptor" }