Add runtime string concat options. Some renaming
This commit is contained in:
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen;
|
package org.jetbrains.kotlin.codegen;
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import com.intellij.openapi.util.Pair;
|
import com.intellij.openapi.util.Pair;
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
import com.intellij.util.ArrayUtil;
|
import com.intellij.util.ArrayUtil;
|
||||||
@@ -52,7 +51,6 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isBoolean;
|
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isBoolean;
|
||||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isPrimitiveClass;
|
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isPrimitiveClass;
|
||||||
@@ -495,12 +493,12 @@ public class DescriptorAsmUtil {
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void genInvokeAppendMethod(@NotNull StringAppendGenerator generator, @NotNull Type type, @Nullable KotlinType kotlinType) {
|
public static void genInvokeAppendMethod(@NotNull StringConcatGenerator generator, @NotNull Type type, @Nullable KotlinType kotlinType) {
|
||||||
genInvokeAppendMethod(generator, type, kotlinType, null);
|
genInvokeAppendMethod(generator, type, kotlinType, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void genInvokeAppendMethod(
|
public static void genInvokeAppendMethod(
|
||||||
@NotNull StringAppendGenerator generator,
|
@NotNull StringConcatGenerator generator,
|
||||||
@NotNull Type type,
|
@NotNull Type type,
|
||||||
@Nullable KotlinType kotlinType,
|
@Nullable KotlinType kotlinType,
|
||||||
@Nullable KotlinTypeMapper typeMapper
|
@Nullable KotlinTypeMapper typeMapper
|
||||||
|
|||||||
@@ -925,7 +925,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return StackValue.operation(type, v -> {
|
return StackValue.operation(type, v -> {
|
||||||
StringAppendGenerator generator = StringAppendGenerator.Companion.create(state, v);
|
StringConcatGenerator generator = StringConcatGenerator.Companion.create(state, v);
|
||||||
generator.genStringBuilderConstructorIfNeded();
|
generator.genStringBuilderConstructorIfNeded();
|
||||||
invokeAppendForEntries(generator, entries);
|
invokeAppendForEntries(generator, entries);
|
||||||
generator.genToString();
|
generator.genToString();
|
||||||
@@ -934,7 +934,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void invokeAppendForEntries(StringAppendGenerator generator, List<StringTemplateEntry> entries) {
|
private void invokeAppendForEntries(StringConcatGenerator generator, List<StringTemplateEntry> entries) {
|
||||||
for (StringTemplateEntry entry : entries) {
|
for (StringTemplateEntry entry : entries) {
|
||||||
if (entry instanceof StringTemplateEntry.Expression) {
|
if (entry instanceof StringTemplateEntry.Expression) {
|
||||||
invokeAppend(generator, ((StringTemplateEntry.Expression) entry).expression);
|
invokeAppend(generator, ((StringTemplateEntry.Expression) entry).expression);
|
||||||
@@ -4300,7 +4300,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invokeAppend(StringAppendGenerator generator, KtExpression expr) {
|
public void invokeAppend(StringConcatGenerator generator, KtExpression expr) {
|
||||||
expr = KtPsiUtil.safeDeparenthesize(expr);
|
expr = KtPsiUtil.safeDeparenthesize(expr);
|
||||||
|
|
||||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expr);
|
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expr);
|
||||||
|
|||||||
+1
-1
@@ -102,7 +102,7 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
|||||||
|
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
|
|
||||||
StringAppendGenerator generator = StringAppendGenerator.Companion.create(generationState, iv);
|
StringConcatGenerator generator = StringConcatGenerator.Companion.create(generationState, iv);
|
||||||
generator.genStringBuilderConstructorIfNeded();
|
generator.genStringBuilderConstructorIfNeded();
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
|
|
||||||
|
|||||||
+8
-8
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.codegen
|
|||||||
|
|
||||||
import com.google.common.collect.Sets
|
import com.google.common.collect.Sets
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.config.JvmTarget
|
import org.jetbrains.kotlin.config.JvmRuntimeStringConcat
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE
|
||||||
import org.jetbrains.org.objectweb.asm.Handle
|
import org.jetbrains.org.objectweb.asm.Handle
|
||||||
@@ -16,14 +16,14 @@ import org.jetbrains.org.objectweb.asm.Type
|
|||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
import java.lang.StringBuilder
|
import java.lang.StringBuilder
|
||||||
|
|
||||||
class StringAppendGenerator(val useInvokeDynamic: Boolean, val mv: InstructionAdapter) {
|
class StringConcatGenerator(val mode: JvmRuntimeStringConcat, val mv: InstructionAdapter) {
|
||||||
|
|
||||||
private val template = StringBuilder("")
|
private val template = StringBuilder("")
|
||||||
private val paramTypes = arrayListOf<Type>()
|
private val paramTypes = arrayListOf<Type>()
|
||||||
|
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun genStringBuilderConstructorIfNeded(swap: Boolean = false) {
|
fun genStringBuilderConstructorIfNeded(swap: Boolean = false) {
|
||||||
if (useInvokeDynamic) return
|
if (mode.isDynamic) return
|
||||||
mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder")
|
mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder")
|
||||||
mv.dup()
|
mv.dup()
|
||||||
mv.invokespecial("java/lang/StringBuilder", "<init>", "()V", false)
|
mv.invokespecial("java/lang/StringBuilder", "<init>", "()V", false)
|
||||||
@@ -33,7 +33,7 @@ class StringAppendGenerator(val useInvokeDynamic: Boolean, val mv: InstructionAd
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun addCharConstant(value: Char) {
|
fun addCharConstant(value: Char) {
|
||||||
if (!useInvokeDynamic) {
|
if (!mode.isDynamic) {
|
||||||
mv.iconst(value.toInt())
|
mv.iconst(value.toInt())
|
||||||
invokeAppend(Type.CHAR_TYPE)
|
invokeAppend(Type.CHAR_TYPE)
|
||||||
} else {
|
} else {
|
||||||
@@ -42,7 +42,7 @@ class StringAppendGenerator(val useInvokeDynamic: Boolean, val mv: InstructionAd
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun addStringConstant(value: String) {
|
fun addStringConstant(value: String) {
|
||||||
if (!useInvokeDynamic) {
|
if (!mode.isDynamic) {
|
||||||
mv.aconst(value)
|
mv.aconst(value)
|
||||||
invokeAppend(JAVA_STRING_TYPE)
|
invokeAppend(JAVA_STRING_TYPE)
|
||||||
} else {
|
} else {
|
||||||
@@ -51,7 +51,7 @@ class StringAppendGenerator(val useInvokeDynamic: Boolean, val mv: InstructionAd
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun invokeAppend(type: Type) {
|
fun invokeAppend(type: Type) {
|
||||||
if (!useInvokeDynamic) {
|
if (!mode.isDynamic) {
|
||||||
mv.invokevirtual(
|
mv.invokevirtual(
|
||||||
"java/lang/StringBuilder",
|
"java/lang/StringBuilder",
|
||||||
"append",
|
"append",
|
||||||
@@ -71,7 +71,7 @@ class StringAppendGenerator(val useInvokeDynamic: Boolean, val mv: InstructionAd
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun genToString() {
|
fun genToString() {
|
||||||
if (!useInvokeDynamic) {
|
if (!mode.isDynamic) {
|
||||||
mv.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false)
|
mv.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false)
|
||||||
} else {
|
} else {
|
||||||
//if state was flushed in `invokeAppend` do nothing
|
//if state was flushed in `invokeAppend` do nothing
|
||||||
@@ -114,7 +114,7 @@ class StringAppendGenerator(val useInvokeDynamic: Boolean, val mv: InstructionAd
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun create(state: GenerationState, mv: InstructionAdapter) =
|
fun create(state: GenerationState, mv: InstructionAdapter) =
|
||||||
StringAppendGenerator(/*TODO: add flag*/state.target.bytecodeVersion >= JvmTarget.JVM_9.bytecodeVersion, mv)
|
StringConcatGenerator(state.runtimeStringConcat, mv)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ class Concat : IntrinsicMethod() {
|
|||||||
arguments: List<KtExpression>,
|
arguments: List<KtExpression>,
|
||||||
receiver: StackValue
|
receiver: StackValue
|
||||||
): Type {
|
): Type {
|
||||||
val generator = StringAppendGenerator.create(codegen.state, v)
|
val generator = StringConcatGenerator.create(codegen.state, v)
|
||||||
if (element is KtBinaryExpression && element.operationReference.getReferencedNameElementType() == KtTokens.PLUS) {
|
if (element is KtBinaryExpression && element.operationReference.getReferencedNameElementType() == KtTokens.PLUS) {
|
||||||
// LHS + RHS
|
// LHS + RHS
|
||||||
generator.genStringBuilderConstructorIfNeded()
|
generator.genStringBuilderConstructorIfNeded()
|
||||||
@@ -59,7 +59,7 @@ class Concat : IntrinsicMethod() {
|
|||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable =
|
override fun toCallable(method: CallableMethod): Callable =
|
||||||
object : IntrinsicCallable(method) {
|
object : IntrinsicCallable(method) {
|
||||||
lateinit var generator: StringAppendGenerator
|
lateinit var generator: StringConcatGenerator
|
||||||
override fun invokeMethodWithArguments(
|
override fun invokeMethodWithArguments(
|
||||||
resolvedCall: ResolvedCall<*>,
|
resolvedCall: ResolvedCall<*>,
|
||||||
receiver: StackValue,
|
receiver: StackValue,
|
||||||
@@ -83,8 +83,8 @@ class Concat : IntrinsicMethod() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap, state: GenerationState) {
|
override fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap, state: GenerationState) {
|
||||||
generator = StringAppendGenerator.create(state, v)
|
generator = StringConcatGenerator.create(state, v)
|
||||||
if (!generator.useInvokeDynamic) {
|
if (!generator.mode.isDynamic) {
|
||||||
v.generateNewInstanceDupAndPlaceBeforeStackTop(frameMap, JAVA_STRING_TYPE, "java/lang/StringBuilder")
|
v.generateNewInstanceDupAndPlaceBeforeStackTop(frameMap, JAVA_STRING_TYPE, "java/lang/StringBuilder")
|
||||||
v.invokespecial("java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false)
|
v.invokespecial("java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
package org.jetbrains.kotlin.codegen.intrinsics
|
package org.jetbrains.kotlin.codegen.intrinsics
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.*
|
import org.jetbrains.kotlin.codegen.*
|
||||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
@@ -25,19 +24,19 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
|||||||
class StringPlus : IntrinsicMethod() {
|
class StringPlus : IntrinsicMethod() {
|
||||||
override fun toCallable(method: CallableMethod): Callable =
|
override fun toCallable(method: CallableMethod): Callable =
|
||||||
object : IntrinsicCallable(method) {
|
object : IntrinsicCallable(method) {
|
||||||
private lateinit var generator: StringAppendGenerator
|
private lateinit var generator: StringConcatGenerator
|
||||||
|
|
||||||
override fun invokeMethodWithArguments(
|
override fun invokeMethodWithArguments(
|
||||||
resolvedCall: ResolvedCall<*>,
|
resolvedCall: ResolvedCall<*>,
|
||||||
receiver: StackValue,
|
receiver: StackValue,
|
||||||
codegen: ExpressionCodegen
|
codegen: ExpressionCodegen
|
||||||
): StackValue {
|
): StackValue {
|
||||||
generator = StringAppendGenerator.create(codegen.state, codegen.v)
|
generator = StringConcatGenerator.create(codegen.state, codegen.v)
|
||||||
return super.invokeMethodWithArguments(resolvedCall, receiver, codegen)
|
return super.invokeMethodWithArguments(resolvedCall, receiver, codegen)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun genInvokeInstruction(v: InstructionAdapter) {
|
override fun genInvokeInstruction(v: InstructionAdapter) {
|
||||||
if (!generator.useInvokeDynamic) {
|
if (!generator.mode.isDynamic) {
|
||||||
v.invokestatic(
|
v.invokestatic(
|
||||||
IntrinsicMethods.INTRINSICS_CLASS_NAME, "stringPlus",
|
IntrinsicMethods.INTRINSICS_CLASS_NAME, "stringPlus",
|
||||||
"(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;", false
|
"(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;", false
|
||||||
|
|||||||
@@ -191,6 +191,10 @@ class GenerationState private constructor(
|
|||||||
val languageVersionSettings = configuration.languageVersionSettings
|
val languageVersionSettings = configuration.languageVersionSettings
|
||||||
|
|
||||||
val target = configuration.get(JVMConfigurationKeys.JVM_TARGET) ?: JvmTarget.DEFAULT
|
val target = configuration.get(JVMConfigurationKeys.JVM_TARGET) ?: JvmTarget.DEFAULT
|
||||||
|
val runtimeStringConcat =
|
||||||
|
if (target.bytecodeVersion >= JvmTarget.JVM_9.bytecodeVersion)
|
||||||
|
configuration.get(JVMConfigurationKeys.RUNTIME_STRING_CONCAT) ?: JvmRuntimeStringConcat.DISABLE
|
||||||
|
else JvmRuntimeStringConcat.DISABLE
|
||||||
|
|
||||||
val moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module)
|
val moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module)
|
||||||
val classBuilderMode: ClassBuilderMode = builderFactory.classBuilderMode
|
val classBuilderMode: ClassBuilderMode = builderFactory.classBuilderMode
|
||||||
|
|||||||
+10
@@ -334,6 +334,16 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
|||||||
)
|
)
|
||||||
var emitJvmTypeAnnotations: Boolean by FreezableVar(false)
|
var emitJvmTypeAnnotations: Boolean by FreezableVar(false)
|
||||||
|
|
||||||
|
@Argument(
|
||||||
|
value = "-Xruntime-string-concat",
|
||||||
|
valueDescription = "{disable|enable|indy}",
|
||||||
|
description = """Switch a way in which string concatenation is performed.
|
||||||
|
-Xruntime-string-concat=enable Performs string concatenation via `invokedynamic` 'makeConcatWithConstants'. Works only with `-jvm-target 9` or greater
|
||||||
|
-Xruntime-string-concat=indy Performs string concatenation via `invokedynamic` 'makeConcat'. Works only with `-jvm-target 9` or greater
|
||||||
|
-Xruntime-string-concat=disable Performs string concatenation via `StringBuilder`"""
|
||||||
|
)
|
||||||
|
var runtimeStringConcat: String? by NullableStringFreezableVar(JvmRuntimeStringConcat.DISABLE.name.toLowerCase())
|
||||||
|
|
||||||
@Argument(
|
@Argument(
|
||||||
value = "-Xklib",
|
value = "-Xklib",
|
||||||
valueDescription = "<path>",
|
valueDescription = "<path>",
|
||||||
|
|||||||
@@ -49,6 +49,24 @@ fun CompilerConfiguration.setupJvmSpecificArguments(arguments: K2JVMCompilerArgu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arguments.runtimeStringConcat != null) {
|
||||||
|
val runtimeStringConcat = JvmRuntimeStringConcat.fromString(arguments.runtimeStringConcat!!)
|
||||||
|
if (runtimeStringConcat != null) {
|
||||||
|
put(JVMConfigurationKeys.RUNTIME_STRING_CONCAT, runtimeStringConcat)
|
||||||
|
if (jvmTarget.bytecodeVersion < JvmTarget.JVM_9.bytecodeVersion && runtimeStringConcat != JvmRuntimeStringConcat.DISABLE) {
|
||||||
|
messageCollector.report(
|
||||||
|
WARNING,
|
||||||
|
"`-Xruntime-string-concat=${arguments.runtimeStringConcat}` does nothing with JVM target `${jvmTarget.description}`."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
messageCollector.report(
|
||||||
|
ERROR, "Unknown `runtime-string-concat` mode: ${arguments.jvmTarget}\n" +
|
||||||
|
"Supported versions: ${JvmRuntimeStringConcat.values().joinToString { it.name.toLowerCase() }}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
addAll(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES, arguments.additionalJavaModules?.asList())
|
addAll(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES, arguments.additionalJavaModules?.asList())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -111,6 +111,9 @@ public class JVMConfigurationKeys {
|
|||||||
public static final CompilerConfigurationKey<Boolean> EMIT_JVM_TYPE_ANNOTATIONS =
|
public static final CompilerConfigurationKey<Boolean> EMIT_JVM_TYPE_ANNOTATIONS =
|
||||||
CompilerConfigurationKey.create("Emit JVM type annotations in bytecode");
|
CompilerConfigurationKey.create("Emit JVM type annotations in bytecode");
|
||||||
|
|
||||||
|
public static final CompilerConfigurationKey<JvmRuntimeStringConcat> RUNTIME_STRING_CONCAT =
|
||||||
|
CompilerConfigurationKey.create("Specifies string concatenation scheme");
|
||||||
|
|
||||||
public static final CompilerConfigurationKey<List<String>> KLIB_PATHS =
|
public static final CompilerConfigurationKey<List<String>> KLIB_PATHS =
|
||||||
CompilerConfigurationKey.create("Paths to .klib libraries");
|
CompilerConfigurationKey.create("Paths to .klib libraries");
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.config
|
||||||
|
|
||||||
|
enum class JvmRuntimeStringConcat {
|
||||||
|
DISABLE,
|
||||||
|
ENABLE, // makeConcatWithConstants
|
||||||
|
INDY; // makeConcat
|
||||||
|
|
||||||
|
val isDynamic
|
||||||
|
get() = this != DISABLE
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun fromString(string: String) = values().find { it.name == string.toUpperCase() }
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -81,6 +81,11 @@ where advanced options include:
|
|||||||
profilerPath is a path to libasyncProfiler.so
|
profilerPath is a path to libasyncProfiler.so
|
||||||
Example: -Xprofile=<PATH_TO_ASYNC_PROFILER>/async-profiler/build/libasyncProfiler.so:event=cpu,interval=1ms,threads,start,framebuf=50000000:<SNAPSHOT_DIR_PATH>
|
Example: -Xprofile=<PATH_TO_ASYNC_PROFILER>/async-profiler/build/libasyncProfiler.so:event=cpu,interval=1ms,threads,start,framebuf=50000000:<SNAPSHOT_DIR_PATH>
|
||||||
-Xrepeat=<number> Debug option: Repeats modules compilation <number> times
|
-Xrepeat=<number> Debug option: Repeats modules compilation <number> times
|
||||||
|
-Xruntime-string-concat={disable|enable|indy}
|
||||||
|
Switch a way in which string concatenation is performed.
|
||||||
|
-Xruntime-string-concat=enable Performs string concatenation via `invokedynamic` 'makeConcatWithConstants'. Works only with `-jvm-target 9` or greater
|
||||||
|
-Xruntime-string-concat=indy Performs string concatenation via `invokedynamic` 'makeConcat'. Works only with `-jvm-target 9` or greater
|
||||||
|
-Xruntime-string-concat=disable Performs string concatenation via `StringBuilder`
|
||||||
-Xsanitize-parentheses Transform '(' and ')' in method names to some other character sequence.
|
-Xsanitize-parentheses Transform '(' and ')' in method names to some other character sequence.
|
||||||
This mode can BREAK BINARY COMPATIBILITY and is only supposed to be used to workaround
|
This mode can BREAK BINARY COMPATIBILITY and is only supposed to be used to workaround
|
||||||
problems with parentheses in identifiers on certain platforms
|
problems with parentheses in identifiers on certain platforms
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// KOTLIN_CONFIGURATION_FLAGS: RUNTIME_STRING_CONCAT=enable
|
||||||
// JVM_TARGET: 9
|
// JVM_TARGET: 9
|
||||||
class A
|
class A
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// KOTLIN_CONFIGURATION_FLAGS: RUNTIME_STRING_CONCAT=enable
|
||||||
// JVM_TARGET: 9
|
// JVM_TARGET: 9
|
||||||
|
|
||||||
fun box() {
|
fun box() {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// KOTLIN_CONFIGURATION_FLAGS: RUNTIME_STRING_CONCAT=enable
|
||||||
// JVM_TARGET: 9
|
// JVM_TARGET: 9
|
||||||
fun box() {
|
fun box() {
|
||||||
val z = "0"
|
val z = "0"
|
||||||
|
|||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// KOTLIN_CONFIGURATION_FLAGS: RUNTIME_STRING_CONCAT=enable
|
||||||
// JVM_TARGET: 9
|
// JVM_TARGET: 9
|
||||||
class A
|
class A
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// KOTLIN_CONFIGURATION_FLAGS: RUNTIME_STRING_CONCAT=enable
|
||||||
// JVM_TARGET: 9
|
// JVM_TARGET: 9
|
||||||
fun box(a: String, b: String?) {
|
fun box(a: String, b: String?) {
|
||||||
val sb = StringBuilder();
|
val sb = StringBuilder();
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// KOTLIN_CONFIGURATION_FLAGS: RUNTIME_STRING_CONCAT=enable
|
||||||
// JVM_TARGET: 9
|
// JVM_TARGET: 9
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val z = "0"
|
val z = "0"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// KOTLIN_CONFIGURATION_FLAGS: RUNTIME_STRING_CONCAT=enable
|
||||||
// JVM_TARGET: 9
|
// JVM_TARGET: 9
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val z = "0"
|
val z = "0"
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ abstract class KotlinBaseTest<F : KotlinBaseTest.TestFile> : KtUsefulTestCase()
|
|||||||
"CONSTRUCTOR_CALL_NORMALIZATION_MODE=([a-zA-Z_\\-0-9]*)"
|
"CONSTRUCTOR_CALL_NORMALIZATION_MODE=([a-zA-Z_\\-0-9]*)"
|
||||||
)
|
)
|
||||||
private val ASSERTIONS_MODE_FLAG_PATTERN = Pattern.compile("ASSERTIONS_MODE=([a-zA-Z_0-9-]*)")
|
private val ASSERTIONS_MODE_FLAG_PATTERN = Pattern.compile("ASSERTIONS_MODE=([a-zA-Z_0-9-]*)")
|
||||||
|
private val RUNTIME_STRING_CONCAT = Pattern.compile("RUNTIME_STRING_CONCAT=([a-zA-Z_0-9-]*)")
|
||||||
|
|
||||||
private fun tryApplyBooleanFlag(
|
private fun tryApplyBooleanFlag(
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
@@ -294,6 +295,14 @@ abstract class KotlinBaseTest<F : KotlinBaseTest.TestFile> : KtUsefulTestCase()
|
|||||||
?: error("Wrong ASSERTIONS_MODE value: $flagValueString")
|
?: error("Wrong ASSERTIONS_MODE value: $flagValueString")
|
||||||
configuration.put(JVMConfigurationKeys.ASSERTIONS_MODE, mode)
|
configuration.put(JVMConfigurationKeys.ASSERTIONS_MODE, mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m = RUNTIME_STRING_CONCAT.matcher(flag)
|
||||||
|
if (m.matches()) {
|
||||||
|
val flagValueString = m.group(1)
|
||||||
|
val mode = JvmRuntimeStringConcat.fromString(flagValueString)
|
||||||
|
?: error("Wrong RUNTIME_STRING_CONCAT value: $flagValueString")
|
||||||
|
configuration.put(JVMConfigurationKeys.RUNTIME_STRING_CONCAT, mode)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user