diff --git a/compiler/util/src/org/jetbrains/kotlin/utils/LibraryUtils.kt b/compiler/util/src/org/jetbrains/kotlin/utils/LibraryUtils.kt index 1def8df889a..f8c6a59fca7 100644 --- a/compiler/util/src/org/jetbrains/kotlin/utils/LibraryUtils.kt +++ b/compiler/util/src/org/jetbrains/kotlin/utils/LibraryUtils.kt @@ -20,6 +20,7 @@ import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vfs.VirtualFile import com.intellij.util.Processor +import org.jetbrains.kotlin.utils.fileUtils.withReplacedExtensionOrNull import java.io.* import java.util.Properties import java.util.jar.Attributes @@ -112,37 +113,38 @@ public object LibraryUtils { } platformStatic - public fun readJsFiles(libraries: List): List { - val files = arrayListOf() - val libs = libraries.map { File(it) }.filter { it.exists() } + public fun traverseJsLibraries(libs: List, action: (content: String, path: String)->Unit) { + libs.forEach { traverseJsLibrary(it, action) } + } - for (lib in libs) { - when { - lib.isDirectory() -> - traverseDirectory(lib) { file, path -> - files.add(FileUtil.loadFile(file)) - } - FileUtil.isJarOrZip(lib) -> - traverseArchive(lib) { content, path -> - files.add(content) - } - lib.getName().endsWith(KotlinJavascriptMetadataUtils.JS_EXT) -> - files.add(FileUtil.loadFile(lib)) - else -> - throw IllegalArgumentException("Unknown library format (directory, zip or js file expected): $lib") + platformStatic + public fun traverseJsLibrary(lib: File, action: (content: String, path: String)->Unit) { + when { + lib.isDirectory() -> traverseDirectory(lib, action) + FileUtil.isJarOrZip(lib) -> traverseArchive(lib, action) + lib.getName().endsWith(KotlinJavascriptMetadataUtils.JS_EXT) -> { + lib.runIfFileExists(action) + val jsFile = lib.withReplacedExtensionOrNull(KotlinJavascriptMetadataUtils.META_JS_SUFFIX, KotlinJavascriptMetadataUtils.JS_EXT) + jsFile?.runIfFileExists(action) } + 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) { 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 { override fun process(file: File): Boolean { 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) if (suggestedRelativePath == null) return true - action(file, suggestedRelativePath) + action(FileUtil.loadFile(file), suggestedRelativePath) } return true } }) } - fun traverseDirectory(dir: File, action: (File, relativePath: String) -> Unit) { + fun traverseDirectory(dir: File, action: (content: String, relativePath: String) -> Unit) { try { processDirectory(dir, action) } diff --git a/compiler/util/src/org/jetbrains/kotlin/utils/fileUtils.kt b/compiler/util/src/org/jetbrains/kotlin/utils/fileUtils.kt index 7f108fabd21..e340169223d 100644 --- a/compiler/util/src/org/jetbrains/kotlin/utils/fileUtils.kt +++ b/compiler/util/src/org/jetbrains/kotlin/utils/fileUtils.kt @@ -21,3 +21,14 @@ import java.io.File // TODO: move to stdlib as: // public fun File?.readTextOrEmpty(encoding: String = Charset.defaultCharset().name()): String = this?.readText(encoding) ?: "" 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 +} \ No newline at end of file diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/FunctionReader.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/FunctionReader.kt index 1d1e1cd688f..4ae6038fbb8 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/FunctionReader.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/FunctionReader.kt @@ -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.metadata.inlineStrategy import com.google.gwt.dev.js.ThrowExceptionOnErrorReporter +import com.intellij.openapi.util.io.FileUtil import com.intellij.util.containers.SLRUCache import org.jetbrains.kotlin.builtins.KotlinBuiltIns 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.resolve.descriptorUtil.isExtension import org.jetbrains.kotlin.resolve.inline.InlineStrategy +import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils import org.jetbrains.kotlin.utils.LibraryUtils import org.jetbrains.kotlin.utils.sure import java.io.File +import kotlin.platform.platformStatic // TODO: add hash checksum to defineModule? /** @@ -65,17 +68,16 @@ public class FunctionReader(private val context: TranslationContext) { init { val config = context.getConfig() as LibrarySourcesConfig val libs = config.getLibraries().map { File(it) } - val files = LibraryUtils.readJsFiles(libs.map { it.getPath() }.toList()) - for (file in files) { - val matcher = DEFINE_MODULE_PATTERN.matcher(file) + LibraryUtils.traverseJsLibraries(libs) { fileContent, path -> + val matcher = DEFINE_MODULE_PATTERN.toPattern().matcher(fileContent) while (matcher.find()) { val moduleName = matcher.group(3) val moduleVariable = matcher.group(4) val kotlinVariable = matcher.group(1) assert(moduleName !in moduleJsDefinition) { "Module is defined in more, than one file" } - moduleJsDefinition[moduleName] = file + moduleJsDefinition[moduleName] = fileContent moduleRootVariable[moduleName] = moduleVariable moduleKotlinVariable[moduleName] = kotlinVariable }