提交 bd205317 编写于 作者: S scaventz 提交者: Alexander Udalov

CLI: improve behavior of -include-runtime

1.fix KT-17344: Include kotlin-reflect to resulting jar if "-include-runtime" is specified, unless the -no-reflect option is specified.
2.fix KT-43220: -include-runtime should add .kotlin_builtins to the output
上级 496d857d
...@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector; ...@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector;
import org.jetbrains.kotlin.cli.common.modules.ModuleChunk; import org.jetbrains.kotlin.cli.common.modules.ModuleChunk;
import org.jetbrains.kotlin.cli.common.modules.ModuleXmlParser; import org.jetbrains.kotlin.cli.common.modules.ModuleXmlParser;
import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol;
import org.jetbrains.kotlin.utils.ExceptionUtilsKt; import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
import org.jetbrains.kotlin.utils.PathUtil; import org.jetbrains.kotlin.utils.PathUtil;
...@@ -60,6 +61,7 @@ public class CompileEnvironmentUtil { ...@@ -60,6 +61,7 @@ public class CompileEnvironmentUtil {
OutputStream fos, OutputStream fos,
@Nullable FqName mainClass, @Nullable FqName mainClass,
boolean includeRuntime, boolean includeRuntime,
boolean noReflect,
boolean resetJarTimestamps boolean resetJarTimestamps
) { ) {
try { try {
...@@ -89,6 +91,9 @@ public class CompileEnvironmentUtil { ...@@ -89,6 +91,9 @@ public class CompileEnvironmentUtil {
} }
if (includeRuntime) { if (includeRuntime) {
writeRuntimeToJar(stream, resetJarTimestamps); writeRuntimeToJar(stream, resetJarTimestamps);
if (!noReflect) {
writeReflectToJar(stream, resetJarTimestamps);
}
} }
stream.finish(); stream.finish();
} }
...@@ -98,12 +103,12 @@ public class CompileEnvironmentUtil { ...@@ -98,12 +103,12 @@ public class CompileEnvironmentUtil {
} }
public static void writeToJar( public static void writeToJar(
File jarPath, boolean jarRuntime, boolean resetJarTimestamps, FqName mainClass, OutputFileCollection outputFiles File jarPath, boolean jarRuntime, boolean noReflect, boolean resetJarTimestamps, FqName mainClass, OutputFileCollection outputFiles
) { ) {
FileOutputStream outputStream = null; FileOutputStream outputStream = null;
try { try {
outputStream = new FileOutputStream(jarPath); outputStream = new FileOutputStream(jarPath);
doWriteToJar(outputFiles, outputStream, mainClass, jarRuntime, resetJarTimestamps); doWriteToJar(outputFiles, outputStream, mainClass, jarRuntime, noReflect, resetJarTimestamps);
outputStream.close(); outputStream.close();
} }
catch (FileNotFoundException e) { catch (FileNotFoundException e) {
...@@ -125,13 +130,22 @@ public class CompileEnvironmentUtil { ...@@ -125,13 +130,22 @@ public class CompileEnvironmentUtil {
copyJarImpl(stream, stdlibPath, resetJarTimestamps); copyJarImpl(stream, stdlibPath, resetJarTimestamps);
} }
private static void writeReflectToJar(JarOutputStream stream, boolean resetJarTimestamps) throws IOException {
File reflectPath = PathUtil.getKotlinPathsForCompiler().getReflectPath();
if (!reflectPath.exists()) {
throw new CompileEnvironmentException("Couldn't find kotlin-reflect at " + reflectPath);
}
copyJarImpl(stream, reflectPath, resetJarTimestamps);
}
private static void copyJarImpl(JarOutputStream stream, File jarPath, boolean resetJarTimestamps) throws IOException { private static void copyJarImpl(JarOutputStream stream, File jarPath, boolean resetJarTimestamps) throws IOException {
try (JarInputStream jis = new JarInputStream(new FileInputStream(jarPath))) { try (JarInputStream jis = new JarInputStream(new FileInputStream(jarPath))) {
while (true) { while (true) {
JarEntry e = jis.getNextJarEntry(); JarEntry e = jis.getNextJarEntry();
if (e == null) break; if (e == null) break;
if (!FileUtilRt.extensionEquals(e.getName(), "class") || if ((!FileUtilRt.extensionEquals(e.getName(), "class") &&
!FileUtilRt.extensionEquals(e.getName(), BuiltInSerializerProtocol.BUILTINS_FILE_EXTENSION)) ||
StringsKt.substringAfterLast(e.getName(), "/", e.getName()).equals("module-info.class")) { StringsKt.substringAfterLast(e.getName(), "/", e.getName()).equals("module-info.class")) {
continue; continue;
} }
......
...@@ -86,8 +86,9 @@ object KotlinToJVMBytecodeCompiler { ...@@ -86,8 +86,9 @@ object KotlinToJVMBytecodeCompiler {
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE) val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
if (jarPath != null) { if (jarPath != null) {
val includeRuntime = configuration.get(JVMConfigurationKeys.INCLUDE_RUNTIME, false) val includeRuntime = configuration.get(JVMConfigurationKeys.INCLUDE_RUNTIME, false)
val noReflect = configuration.get(JVMConfigurationKeys.NO_REFLECT, false)
val resetJarTimestamps = !configuration.get(JVMConfigurationKeys.NO_RESET_JAR_TIMESTAMPS, false) val resetJarTimestamps = !configuration.get(JVMConfigurationKeys.NO_RESET_JAR_TIMESTAMPS, false)
CompileEnvironmentUtil.writeToJar(jarPath, includeRuntime, resetJarTimestamps, mainClassFqName, outputFiles) CompileEnvironmentUtil.writeToJar(jarPath, includeRuntime, noReflect, resetJarTimestamps, mainClassFqName, outputFiles)
if (reportOutputFiles) { if (reportOutputFiles) {
val message = OutputMessageUtil.formatOutputMessage(outputFiles.asList().flatMap { it.sourceFiles }.distinct(), jarPath) val message = OutputMessageUtil.formatOutputMessage(outputFiles.asList().flatMap { it.sourceFiles }.distinct(), jarPath)
messageCollector.report(OUTPUT, message) messageCollector.report(OUTPUT, message)
......
...@@ -21,6 +21,7 @@ import java.io.File ...@@ -21,6 +21,7 @@ import java.io.File
fun CompilerConfiguration.setupJvmSpecificArguments(arguments: K2JVMCompilerArguments) { fun CompilerConfiguration.setupJvmSpecificArguments(arguments: K2JVMCompilerArguments) {
put(JVMConfigurationKeys.INCLUDE_RUNTIME, arguments.includeRuntime) put(JVMConfigurationKeys.INCLUDE_RUNTIME, arguments.includeRuntime)
put(JVMConfigurationKeys.NO_REFLECT, arguments.noReflect)
putIfNotNull(JVMConfigurationKeys.FRIEND_PATHS, arguments.friendPaths?.asList()) putIfNotNull(JVMConfigurationKeys.FRIEND_PATHS, arguments.friendPaths?.asList())
......
...@@ -146,4 +146,7 @@ public class JVMConfigurationKeys { ...@@ -146,4 +146,7 @@ public class JVMConfigurationKeys {
public static final CompilerConfigurationKey<Boolean> ENABLE_JVM_PREVIEW = public static final CompilerConfigurationKey<Boolean> ENABLE_JVM_PREVIEW =
CompilerConfigurationKey.create("Enable Java language preview features"); CompilerConfigurationKey.create("Enable Java language preview features");
public static final CompilerConfigurationKey<Boolean> NO_REFLECT =
CompilerConfigurationKey.create("Don't automatically include kotlin-reflect.jar into the output if the output is a jar");
} }
ERR:
noReflect.kt:5:23: warning: call uses reflection API which is not found in compilation classpath. Make sure you have kotlin-reflect.jar in the classpath
String::class.annotations
^
Return code: 0
package noReflect
fun main() {
try {
String::class.annotations
} catch (e: KotlinReflectionNotSupportedError) {
println("KotlinReflectionNotSupportedError has been caught")
}
}
\ No newline at end of file
OUT:
KotlinReflectionNotSupportedError has been caught
Return code: 0
package reflect
fun main() {
String::class.annotations
}
\ No newline at end of file
...@@ -187,4 +187,18 @@ public class CompilerSmokeTest extends CompilerSmokeTestBase { ...@@ -187,4 +187,18 @@ public class CompilerSmokeTest extends CompilerSmokeTestBase {
); );
run("buildFile.run", "-cp", tmpdir.getAbsolutePath(), "MainKt"); run("buildFile.run", "-cp", tmpdir.getAbsolutePath(), "MainKt");
} }
public void testReflect() throws Exception {
String jar = tmpdir.getAbsolutePath() + File.separator + "reflect.jar";
assertEquals("compilation failed", 0,
runCompiler("reflect.compile", "-include-runtime", "reflect.kt", "-d", jar));
run("reflect.run", "-cp", jar, "reflect.ReflectKt");
}
public void testNoReflect() throws Exception {
String jar = tmpdir.getAbsolutePath() + File.separator + "noReflect.jar";
assertEquals("compilation failed", 0,
runCompiler("noReflect.compile", "-include-runtime", "-no-reflect", "noReflect.kt", "-d", jar));
run("noReflect.run", "-cp", jar, "noReflect.NoReflectKt");
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册