J2K MockLibraryUtil: prettify

This commit is contained in:
Alexander Udalov
2017-06-16 15:12:55 +03:00
parent 46a6dc6550
commit 68df1d73e7
@@ -17,31 +17,26 @@
package org.jetbrains.kotlin.test package org.jetbrains.kotlin.test
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import com.intellij.util.ArrayUtil
import com.intellij.util.io.ZipUtil import com.intellij.util.io.ZipUtil
import org.jetbrains.kotlin.cli.common.CLICompiler
import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.js.K2JSCompiler import org.jetbrains.kotlin.cli.js.K2JSCompiler
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
import org.jetbrains.kotlin.preloading.ClassPreloadingUtils import org.jetbrains.kotlin.preloading.ClassPreloadingUtils
import org.jetbrains.kotlin.preloading.Preloader import org.jetbrains.kotlin.preloading.Preloader
import org.jetbrains.kotlin.utils.*
import org.jetbrains.kotlin.utils.PathUtil import org.jetbrains.kotlin.utils.PathUtil
import org.junit.Assert.assertEquals
import java.io.* import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.PrintStream
import java.lang.ref.SoftReference import java.lang.ref.SoftReference
import java.lang.reflect.Method
import java.util.ArrayList
import java.util.Arrays
import java.util.Collections
import java.util.regex.Pattern import java.util.regex.Pattern
import java.util.zip.ZipOutputStream import java.util.zip.ZipOutputStream
import kotlin.reflect.KClass
import org.junit.Assert.assertEquals
object MockLibraryUtil { object MockLibraryUtil {
private var compilerClassLoader = SoftReference<ClassLoader>(null) private var compilerClassLoader = SoftReference<ClassLoader>(null)
@JvmStatic @JvmStatic
@@ -69,19 +64,10 @@ object MockLibraryUtil {
allowKotlinPackage: Boolean, allowKotlinPackage: Boolean,
vararg extraClasspath: String vararg extraClasspath: String
): File { ): File {
try { return compileLibraryToJar(
return compileLibraryToJar( sourcesPath, KotlinTestUtils.tmpDir("testLibrary-" + jarName), jarName, addSources, allowKotlinPackage,
sourcesPath, *extraClasspath
KotlinTestUtils.tmpDir("testLibrary-" + jarName), )
jarName,
addSources,
allowKotlinPackage,
*extraClasspath)
}
catch (e: IOException) {
throw rethrow(e)
}
} }
@JvmStatic @JvmStatic
@@ -93,76 +79,59 @@ object MockLibraryUtil {
allowKotlinPackage: Boolean, allowKotlinPackage: Boolean,
vararg extraClasspath: String vararg extraClasspath: String
): File { ): File {
try { val classesDir = File(contentDir, "classes")
val classesDir = File(contentDir, "classes")
val srcFile = File(sourcesPath) val srcFile = File(sourcesPath)
val kotlinFiles = FileUtil.findFilesByMask(Pattern.compile(".*\\.kt"), srcFile) val kotlinFiles = FileUtil.findFilesByMask(Pattern.compile(".*\\.kt"), srcFile)
if (srcFile.isFile || !kotlinFiles.isEmpty()) { if (srcFile.isFile || kotlinFiles.isNotEmpty()) {
compileKotlin(sourcesPath, classesDir, allowKotlinPackage, *extraClasspath) compileKotlin(sourcesPath, classesDir, allowKotlinPackage, *extraClasspath)
}
val javaFiles = FileUtil.findFilesByMask(Pattern.compile(".*\\.java"), srcFile)
if (javaFiles.isNotEmpty()) {
val classpath = mutableListOf<String>()
classpath += ForTestCompileRuntime.runtimeJarForTests().path
classpath += KotlinTestUtils.getAnnotationsJar().path
classpath += extraClasspath
// Probably no kotlin files were present, so dir might not have been created after kotlin compiler
if (classesDir.exists()) {
classpath += classesDir.path
}
else {
FileUtil.createDirectory(classesDir)
} }
val javaFiles = FileUtil.findFilesByMask(Pattern.compile(".*\\.java"), srcFile) val options = listOf(
if (!javaFiles.isEmpty()) { "-classpath", classpath.joinToString(File.pathSeparator),
val classpath = ArrayList<String>() "-d", classesDir.path
classpath.add(ForTestCompileRuntime.runtimeJarForTests().path) )
classpath.add(KotlinTestUtils.getAnnotationsJar().path)
Collections.addAll(classpath, *extraClasspath)
// Probably no kotlin files were present, so dir might not have been created after kotlin compiler KotlinTestUtils.compileJavaFiles(javaFiles, options)
if (classesDir.exists()) {
classpath.add(classesDir.path)
}
else {
FileUtil.createDirectory(classesDir)
}
val options = Arrays.asList(
"-classpath", StringUtil.join(classpath, File.pathSeparator),
"-d", classesDir.path
)
KotlinTestUtils.compileJavaFiles(javaFiles, options)
}
return createJarFile(contentDir, classesDir, sourcesPath, jarName, addSources)
}
catch (e: IOException) {
throw rethrow(e)
} }
return createJarFile(contentDir, classesDir, sourcesPath, jarName, addSources)
} }
private fun compileJsLibraryToJar( private fun compileJsLibraryToJar(sourcesPath: String, jarName: String, addSources: Boolean): File {
sourcesPath: String, val contentDir = KotlinTestUtils.tmpDir("testLibrary-" + jarName)
jarName: String,
addSources: Boolean
): File {
try {
val contentDir = KotlinTestUtils.tmpDir("testLibrary-" + jarName)
val outDir = File(contentDir, "out") val outDir = File(contentDir, "out")
val outputFile = File(outDir, jarName + ".js") val outputFile = File(outDir, jarName + ".js")
compileKotlin2JS(sourcesPath, outputFile) compileKotlin2JS(sourcesPath, outputFile)
return createJarFile(contentDir, outDir, sourcesPath, jarName, addSources)
}
catch (e: IOException) {
throw rethrow(e)
}
return createJarFile(contentDir, outDir, sourcesPath, jarName, addSources)
} }
@Throws(IOException::class)
fun createJarFile(contentDir: File, dirToAdd: File, sourcesPath: String, jarName: String, addSources: Boolean): File { fun createJarFile(contentDir: File, dirToAdd: File, sourcesPath: String, jarName: String, addSources: Boolean): File {
val jarFile = File(contentDir, jarName + ".jar") val jarFile = File(contentDir, jarName + ".jar")
val zip = ZipOutputStream(FileOutputStream(jarFile)) ZipOutputStream(FileOutputStream(jarFile)).use { zip ->
ZipUtil.addDirToZipRecursively(zip, jarFile, dirToAdd, "", null, null) ZipUtil.addDirToZipRecursively(zip, jarFile, dirToAdd, "", null, null)
if (addSources) { if (addSources) {
ZipUtil.addDirToZipRecursively(zip, jarFile, File(sourcesPath), "src", null, null) ZipUtil.addDirToZipRecursively(zip, jarFile, File(sourcesPath), "src", null, null)
}
} }
zip.close()
return jarFile return jarFile
} }
@@ -177,19 +146,11 @@ object MockLibraryUtil {
// Runs compiler in custom class loader to avoid effects caused by replacing Application with another one created in compiler. // Runs compiler in custom class loader to avoid effects caused by replacing Application with another one created in compiler.
private fun runCompiler(compilerClass: Class<*>, args: List<String>) { private fun runCompiler(compilerClass: Class<*>, args: List<String>) {
try { val outStream = ByteArrayOutputStream()
val outStream = ByteArrayOutputStream() val compiler = compilerClass.newInstance()
val compiler = compilerClass.newInstance() val execMethod = compilerClass.getMethod("exec", PrintStream::class.java, Array<String>::class.java)
val execMethod = compilerClass.getMethod("exec", PrintStream::class.java, Array<String>::class.java) val invocationResult = execMethod.invoke(compiler, PrintStream(outStream), args.toTypedArray()) as Enum<*>
assertEquals(String(outStream.toByteArray()), ExitCode.OK.name, invocationResult.name)
val invocationResult = execMethod.invoke(compiler, PrintStream(outStream), ArrayUtil.toStringArray(args)) as Enum<*>
assertEquals(String(outStream.toByteArray()), ExitCode.OK.name, invocationResult.name)
}
catch (e: Throwable) {
throw rethrow(e)
}
} }
@JvmStatic @JvmStatic
@@ -203,72 +164,51 @@ object MockLibraryUtil {
allowKotlinPackage: Boolean, allowKotlinPackage: Boolean,
vararg extraClasspath: String vararg extraClasspath: String
) { ) {
val classpath = ArrayList<String>() val classpath = mutableListOf<String>()
if (File(sourcesPath).isDirectory) { if (File(sourcesPath).isDirectory) {
classpath.add(sourcesPath) classpath += sourcesPath
} }
Collections.addAll(classpath, *extraClasspath) classpath += extraClasspath
val args = ArrayList<String>() val args = mutableListOf(
args.add(sourcesPath) sourcesPath,
args.add("-d") "-d", outDir.absolutePath,
args.add(outDir.absolutePath) "-classpath", classpath.joinToString(File.pathSeparator)
args.add("-classpath") )
args.add(StringUtil.join(classpath, File.pathSeparator))
if (allowKotlinPackage) { if (allowKotlinPackage) {
args.add("-Xallow-kotlin-package") args += "-Xallow-kotlin-package"
} }
runJvmCompiler(args) runJvmCompiler(args)
} }
private fun compileKotlin2JS(sourcesPath: String, outputFile: File) { private fun compileKotlin2JS(sourcesPath: String, outputFile: File) {
val args = ArrayList<String>() runJsCompiler(listOf("-meta-info", "-output", outputFile.absolutePath, sourcesPath))
args.add("-meta-info")
args.add("-output")
args.add(outputFile.absolutePath)
args.add(sourcesPath)
runJsCompiler(args)
} }
fun compileKotlinModule(modulePath: String) { fun compileKotlinModule(modulePath: String) {
runJvmCompiler(Arrays.asList("-no-stdlib", "-module", modulePath)) runJvmCompiler(listOf("-no-stdlib", "-module", modulePath))
} }
private val compiler2JVMClass: Class<*> private val compiler2JVMClass: Class<*>
@Synchronized get() = loadCompilerClass(K2JVMCompiler::class.java.name) @Synchronized get() = loadCompilerClass(K2JVMCompiler::class)
private val compiler2JSClass: Class<*> private val compiler2JSClass: Class<*>
@Synchronized get() = loadCompilerClass(K2JSCompiler::class.java.name) @Synchronized get() = loadCompilerClass(K2JSCompiler::class)
@Synchronized private fun loadCompilerClass(compilerClassName: String): Class<*> { @Synchronized
try { private fun loadCompilerClass(compilerClass: KClass<out CLICompiler<*>>): Class<*> {
var classLoader = compilerClassLoader.get() val classLoader = compilerClassLoader.get() ?: createCompilerClassLoader().also { classLoader ->
if (classLoader == null) { compilerClassLoader = SoftReference<ClassLoader>(classLoader)
classLoader = createCompilerClassLoader()
compilerClassLoader = SoftReference<ClassLoader>(classLoader)
}
return classLoader.loadClass(compilerClassName)
} }
catch (e: Throwable) { return classLoader.loadClass(compilerClass.java.name)
throw rethrow(e)
}
} }
@Synchronized private fun createCompilerClassLoader(): ClassLoader { @Synchronized
try { private fun createCompilerClassLoader(): ClassLoader {
val kotlinCompilerJar = File(PathUtil.getKotlinPathsForDistDirectory().libPath, "kotlin-compiler.jar") return ClassPreloadingUtils.preloadClasses(
return ClassPreloadingUtils.preloadClasses( listOf(PathUtil.getKotlinPathsForDistDirectory().compilerPath),
listOf(kotlinCompilerJar), Preloader.DEFAULT_CLASS_NUMBER_ESTIMATE, null, null, null Preloader.DEFAULT_CLASS_NUMBER_ESTIMATE, null, null
) )
}
catch (e: Throwable) {
throw rethrow(e)
}
} }
} }