JS: search inline function in .js file corresponding to module's

.meta.js
This commit is contained in:
Alexey Tsvetkov
2015-05-18 18:34:55 +03:00
parent 0488229a61
commit b2238c0ebf
3 changed files with 41 additions and 26 deletions
@@ -20,6 +20,7 @@ import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.Processor import com.intellij.util.Processor
import org.jetbrains.kotlin.utils.fileUtils.withReplacedExtensionOrNull
import java.io.* import java.io.*
import java.util.Properties import java.util.Properties
import java.util.jar.Attributes import java.util.jar.Attributes
@@ -112,37 +113,38 @@ public object LibraryUtils {
} }
platformStatic platformStatic
public fun readJsFiles(libraries: List<String>): List<String> { public fun traverseJsLibraries(libs: List<File>, action: (content: String, path: String)->Unit) {
val files = arrayListOf<String>() libs.forEach { traverseJsLibrary(it, action) }
val libs = libraries.map { File(it) }.filter { it.exists() } }
for (lib in libs) { platformStatic
when { public fun traverseJsLibrary(lib: File, action: (content: String, path: String)->Unit) {
lib.isDirectory() -> when {
traverseDirectory(lib) { file, path -> lib.isDirectory() -> traverseDirectory(lib, action)
files.add(FileUtil.loadFile(file)) FileUtil.isJarOrZip(lib) -> traverseArchive(lib, action)
} lib.getName().endsWith(KotlinJavascriptMetadataUtils.JS_EXT) -> {
FileUtil.isJarOrZip(lib) -> lib.runIfFileExists(action)
traverseArchive(lib) { content, path -> val jsFile = lib.withReplacedExtensionOrNull(KotlinJavascriptMetadataUtils.META_JS_SUFFIX, KotlinJavascriptMetadataUtils.JS_EXT)
files.add(content) jsFile?.runIfFileExists(action)
}
lib.getName().endsWith(KotlinJavascriptMetadataUtils.JS_EXT) ->
files.add(FileUtil.loadFile(lib))
else ->
throw IllegalArgumentException("Unknown library format (directory, zip or js file expected): $lib")
} }
else ->
throw IllegalArgumentException("Unknown library format (directory, zip or js file expected): $lib")
} }
}
return files private fun File.runIfFileExists(action: (content: String, path: String)->Unit) {
if (isFile()) {
action(FileUtil.loadFile(this), "")
}
} }
private fun copyJsFilesFromDirectory(dir: File, outputLibraryJsPath: String) { private fun copyJsFilesFromDirectory(dir: File, outputLibraryJsPath: String) {
traverseDirectory(dir) { traverseDirectory(dir) {
file, relativePath -> FileUtil.copy(file, File(outputLibraryJsPath, relativePath)) content, relativePath -> FileUtil.writeToFile(File(outputLibraryJsPath, relativePath), content)
} }
} }
private fun processDirectory(dir: File, action: (File, relativePath: String) -> Unit) { private fun processDirectory(dir: File, action: (content: String, relativePath: String) -> Unit) {
FileUtil.processFilesRecursively(dir, object : Processor<File> { FileUtil.processFilesRecursively(dir, object : Processor<File> {
override fun process(file: File): Boolean { override fun process(file: File): Boolean {
val relativePath = FileUtil.getRelativePath(dir, file) ?: throw IllegalArgumentException("relativePath should not be null " + dir + " " + file) val relativePath = FileUtil.getRelativePath(dir, file) ?: throw IllegalArgumentException("relativePath should not be null " + dir + " " + file)
@@ -150,14 +152,14 @@ public object LibraryUtils {
val suggestedRelativePath = getSuggestedPath(relativePath) val suggestedRelativePath = getSuggestedPath(relativePath)
if (suggestedRelativePath == null) return true if (suggestedRelativePath == null) return true
action(file, suggestedRelativePath) action(FileUtil.loadFile(file), suggestedRelativePath)
} }
return true return true
} }
}) })
} }
fun traverseDirectory(dir: File, action: (File, relativePath: String) -> Unit) { fun traverseDirectory(dir: File, action: (content: String, relativePath: String) -> Unit) {
try { try {
processDirectory(dir, action) processDirectory(dir, action)
} }
@@ -21,3 +21,14 @@ import java.io.File
// TODO: move to stdlib as: // TODO: move to stdlib as:
// public fun File?.readTextOrEmpty(encoding: String = Charset.defaultCharset().name()): String = this?.readText(encoding) ?: "" // public fun File?.readTextOrEmpty(encoding: String = Charset.defaultCharset().name()): String = this?.readText(encoding) ?: ""
public fun File?.readTextOrEmpty(): String = this?.readText() ?: "" public fun File?.readTextOrEmpty(): String = this?.readText() ?: ""
public fun File.withReplacedExtensionOrNull(oldExt: String, newExt: String): File? {
if (getName().endsWith(oldExt)) {
val path = getPath()
val pathWithoutExt = path.substring(0, path.length() - oldExt.length())
val pathWithNewExt = pathWithoutExt + newExt
return File(pathWithNewExt)
}
return null
}
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.js.inline
import com.google.dart.compiler.backend.js.ast.* import com.google.dart.compiler.backend.js.ast.*
import com.google.dart.compiler.backend.js.ast.metadata.inlineStrategy import com.google.dart.compiler.backend.js.ast.metadata.inlineStrategy
import com.google.gwt.dev.js.ThrowExceptionOnErrorReporter import com.google.gwt.dev.js.ThrowExceptionOnErrorReporter
import com.intellij.openapi.util.io.FileUtil
import com.intellij.util.containers.SLRUCache import com.intellij.util.containers.SLRUCache
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
@@ -32,9 +33,11 @@ import org.jetbrains.kotlin.js.translate.reference.CallExpressionTranslator
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getExternalModuleName import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getExternalModuleName
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.resolve.inline.InlineStrategy import org.jetbrains.kotlin.resolve.inline.InlineStrategy
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils
import org.jetbrains.kotlin.utils.LibraryUtils import org.jetbrains.kotlin.utils.LibraryUtils
import org.jetbrains.kotlin.utils.sure import org.jetbrains.kotlin.utils.sure
import java.io.File import java.io.File
import kotlin.platform.platformStatic
// TODO: add hash checksum to defineModule? // TODO: add hash checksum to defineModule?
/** /**
@@ -65,17 +68,16 @@ public class FunctionReader(private val context: TranslationContext) {
init { init {
val config = context.getConfig() as LibrarySourcesConfig val config = context.getConfig() as LibrarySourcesConfig
val libs = config.getLibraries().map { File(it) } val libs = config.getLibraries().map { File(it) }
val files = LibraryUtils.readJsFiles(libs.map { it.getPath() }.toList())
for (file in files) { LibraryUtils.traverseJsLibraries(libs) { fileContent, path ->
val matcher = DEFINE_MODULE_PATTERN.matcher(file) val matcher = DEFINE_MODULE_PATTERN.toPattern().matcher(fileContent)
while (matcher.find()) { while (matcher.find()) {
val moduleName = matcher.group(3) val moduleName = matcher.group(3)
val moduleVariable = matcher.group(4) val moduleVariable = matcher.group(4)
val kotlinVariable = matcher.group(1) val kotlinVariable = matcher.group(1)
assert(moduleName !in moduleJsDefinition) { "Module is defined in more, than one file" } assert(moduleName !in moduleJsDefinition) { "Module is defined in more, than one file" }
moduleJsDefinition[moduleName] = file moduleJsDefinition[moduleName] = fileContent
moduleRootVariable[moduleName] = moduleVariable moduleRootVariable[moduleName] = moduleVariable
moduleKotlinVariable[moduleName] = kotlinVariable moduleKotlinVariable[moduleName] = kotlinVariable
} }